authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-26 18:29:07-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-26 18:29:07-04:00
log2cbad364c1d23b64ae064f8547590c133b4f070a
treeb7ff7ef918cb2a8bb3a55eacfa0ca9b95b05cafd
parentfd575fe1f3b45806f2cf823a2abe3727d381d4ed

add compile error for ignoring return value of while loop bodies

closes #1049

4 files changed, 36 insertions(+), 4 deletions(-)

src/analyze.cpp+1-1
......@@ -4056,7 +4056,7 @@ void analyze_fn_ir(CodeGen *g, FnTableEntry *fn_table_entry, AstNode *return_typ
40564056 }
40574057
40584058 if (g->verbose_ir) {
4059 fprintf(stderr, "{ // (analyzed)\n");
4059 fprintf(stderr, "fn %s() { // (analyzed)\n", buf_ptr(&fn_table_entry->symbol_name));
40604060 ir_print(g, stderr, &fn_table_entry->analyzed_executable, 4);
40614061 fprintf(stderr, "}\n");
40624062 }
src/ir.cpp+9-3
......@@ -5251,8 +5251,10 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
52515251 if (body_result == irb->codegen->invalid_instruction)
52525252 return body_result;
52535253
5254 if (!instr_is_unreachable(body_result))
5254 if (!instr_is_unreachable(body_result)) {
5255 ir_mark_gen(ir_build_check_statement_is_void(irb, payload_scope, node->data.while_expr.body, body_result));
52555256 ir_mark_gen(ir_build_br(irb, payload_scope, node, continue_block, is_comptime));
5257 }
52565258
52575259 if (continue_expr_node) {
52585260 ir_set_cursor_at_end_and_append_block(irb, continue_block);
......@@ -5331,8 +5333,10 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
53315333 if (body_result == irb->codegen->invalid_instruction)
53325334 return body_result;
53335335
5334 if (!instr_is_unreachable(body_result))
5336 if (!instr_is_unreachable(body_result)) {
5337 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.while_expr.body, body_result));
53355338 ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime));
5339 }
53365340
53375341 if (continue_expr_node) {
53385342 ir_set_cursor_at_end_and_append_block(irb, continue_block);
......@@ -5392,8 +5396,10 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
53925396 if (body_result == irb->codegen->invalid_instruction)
53935397 return body_result;
53945398
5395 if (!instr_is_unreachable(body_result))
5399 if (!instr_is_unreachable(body_result)) {
5400 ir_mark_gen(ir_build_check_statement_is_void(irb, scope, node->data.while_expr.body, body_result));
53965401 ir_mark_gen(ir_build_br(irb, scope, node, continue_block, is_comptime));
5402 }
53975403
53985404 if (continue_expr_node) {
53995405 ir_set_cursor_at_end_and_append_block(irb, continue_block);
src/ir_print.cpp+4
......@@ -45,6 +45,10 @@ static void ir_print_var_instruction(IrPrint *irp, IrInstruction *instruction) {
4545}
4646
4747static void ir_print_other_instruction(IrPrint *irp, IrInstruction *instruction) {
48 if (instruction == nullptr) {
49 fprintf(irp->f, "(null)");
50 return;
51 }
4852 if (instruction->value.special != ConstValSpecialRuntime) {
4953 ir_print_const_value(irp, &instruction->value);
5054 } else {
test/compile_errors.zig+22
......@@ -1,6 +1,28 @@
11const tests = @import("tests.zig");
22
33pub fn addCases(cases: *tests.CompileErrorContext) void {
4 cases.add(
5 "while loop body expression ignored",
6 \\fn returns() usize {
7 \\ return 2;
8 \\}
9 \\export fn f1() void {
10 \\ while (true) returns();
11 \\}
12 \\export fn f2() void {
13 \\ var x: ?i32 = null;
14 \\ while (x) |_| returns();
15 \\}
16 \\export fn f3() void {
17 \\ var x: error!i32 = error.Bad;
18 \\ while (x) |_| returns() else |_| unreachable;
19 \\}
20 ,
21 ".tmp_source.zig:5:25: error: expression value is ignored",
22 ".tmp_source.zig:9:26: error: expression value is ignored",
23 ".tmp_source.zig:13:26: error: expression value is ignored",
24 );
25
426 cases.add(
527 "missing parameter name of generic function",
628 \\fn dump(var) void {}