authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-06-06 11:31:54-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-06-06 11:31:54-07:00
log41bf81dc3231eb763c93eb95b152e7ab8d3c5af8
tree6610d43dfab44f104e7894f3d31991ff38821512
parent1bdc2b777bc247c52942189666bc484d8e740b16

Revert "Treat blocks with "return" as "noreturn""

This reverts commit 135b91aecd9be1f6f5806b667e07e383dd481198. "endsWithBreak()" is not a meaningful question to ask and should not be used this way. A simple example that defeats this logic is: ```zig export fn entry() void { outer: { { break :outer; } return; } } ```

3 files changed, 0 insertions(+), 37 deletions(-)

src/AstGen.zig-10
...@@ -1967,9 +1967,6 @@ fn blockExpr(...@@ -1967,9 +1967,6 @@ fn blockExpr(
1967 }1967 }
19681968
1969 try blockExprStmts(gz, scope, statements);1969 try blockExprStmts(gz, scope, statements);
1970 if (gz.endsWithNoReturn() and !gz.endsWithBreak()) {
1971 return Zir.Inst.Ref.unreachable_value;
1972 }
1973 return rvalue(gz, rl, .void_value, block_node);1970 return rvalue(gz, rl, .void_value, block_node);
1974}1971}
19751972
...@@ -9933,13 +9930,6 @@ const GenZir = struct {...@@ -9933,13 +9930,6 @@ const GenZir = struct {
9933 return tags[last_inst].isNoReturn();9930 return tags[last_inst].isNoReturn();
9934 }9931 }
99359932
9936 fn endsWithBreak(gz: GenZir) bool {
9937 if (gz.isEmpty()) return false;
9938 const tags = gz.astgen.instructions.items(.tag);
9939 const last_inst = gz.instructions.items[gz.instructions.items.len - 1];
9940 return tags[last_inst].isBreak();
9941 }
9942
9943 /// TODO all uses of this should be replaced with uses of `endsWithNoReturn`.9933 /// TODO all uses of this should be replaced with uses of `endsWithNoReturn`.
9944 fn refIsNoReturn(gz: GenZir, inst_ref: Zir.Inst.Ref) bool {9934 fn refIsNoReturn(gz: GenZir, inst_ref: Zir.Inst.Ref) bool {
9945 if (inst_ref == .unreachable_value) return true;9935 if (inst_ref == .unreachable_value) return true;
src/Zir.zig-13
...@@ -1250,19 +1250,6 @@ pub const Inst = struct {...@@ -1250,19 +1250,6 @@ pub const Inst = struct {
1250 };1250 };
1251 }1251 }
12521252
1253 /// Returns whether the instruction is a "break". This differs from
1254 /// isNoReturn because a "break" in a block statement is not a
1255 /// "noreturn" for the outer scope, whereas the other "noreturn"
1256 /// instructions are.
1257 pub fn isBreak(tag: Tag) bool {
1258 return switch (tag) {
1259 .@"break",
1260 .break_inline,
1261 => true,
1262 else => false,
1263 };
1264 }
1265
1266 /// AstGen uses this to find out if `Ref.void_value` should be used in place1253 /// AstGen uses this to find out if `Ref.void_value` should be used in place
1267 /// of the result of a given instruction. This allows Sema to forego adding1254 /// of the result of a given instruction. This allows Sema to forego adding
1268 /// the instruction to the map after analysis.1255 /// the instruction to the map after analysis.
test/cases/compile_errors/stage2/code_after_return_in_block_is_unreachable.zig deleted-14
...@@ -1,14 +0,0 @@
1export fn entry() void {
2 {
3 return;
4 }
5
6 return;
7}
8
9// error
10// target=native
11//
12// :6:5: error: unreachable code
13// :2:5: note: control flow is diverted here
14