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...@@ -4056,7 +4056,7 @@ void analyze_fn_ir(CodeGen *g, FnTableEntry *fn_table_entry, AstNode *return_typ
4056 }4056 }
40574057
4058 if (g->verbose_ir) {4058 if (g->verbose_ir) {
4059 fprintf(stderr, "{ // (analyzed)\n");4059 fprintf(stderr, "fn %s() { // (analyzed)\n", buf_ptr(&fn_table_entry->symbol_name));
4060 ir_print(g, stderr, &fn_table_entry->analyzed_executable, 4);4060 ir_print(g, stderr, &fn_table_entry->analyzed_executable, 4);
4061 fprintf(stderr, "}\n");4061 fprintf(stderr, "}\n");
4062 }4062 }
src/ir.cpp+9-3
...@@ -5251,8 +5251,10 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n...@@ -5251,8 +5251,10 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
5251 if (body_result == irb->codegen->invalid_instruction)5251 if (body_result == irb->codegen->invalid_instruction)
5252 return body_result;5252 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));
5255 ir_mark_gen(ir_build_br(irb, payload_scope, node, continue_block, is_comptime));5256 ir_mark_gen(ir_build_br(irb, payload_scope, node, continue_block, is_comptime));
5257 }
52565258
5257 if (continue_expr_node) {5259 if (continue_expr_node) {
5258 ir_set_cursor_at_end_and_append_block(irb, continue_block);5260 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...@@ -5331,8 +5333,10 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
5331 if (body_result == irb->codegen->invalid_instruction)5333 if (body_result == irb->codegen->invalid_instruction)
5332 return body_result;5334 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));
5335 ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime));5338 ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime));
5339 }
53365340
5337 if (continue_expr_node) {5341 if (continue_expr_node) {
5338 ir_set_cursor_at_end_and_append_block(irb, continue_block);5342 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...@@ -5392,8 +5396,10 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
5392 if (body_result == irb->codegen->invalid_instruction)5396 if (body_result == irb->codegen->invalid_instruction)
5393 return body_result;5397 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));
5396 ir_mark_gen(ir_build_br(irb, scope, node, continue_block, is_comptime));5401 ir_mark_gen(ir_build_br(irb, scope, node, continue_block, is_comptime));
5402 }
53975403
5398 if (continue_expr_node) {5404 if (continue_expr_node) {
5399 ir_set_cursor_at_end_and_append_block(irb, continue_block);5405 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) {...@@ -45,6 +45,10 @@ static void ir_print_var_instruction(IrPrint *irp, IrInstruction *instruction) {
45}45}
4646
47static void ir_print_other_instruction(IrPrint *irp, IrInstruction *instruction) {47static void ir_print_other_instruction(IrPrint *irp, IrInstruction *instruction) {
48 if (instruction == nullptr) {
49 fprintf(irp->f, "(null)");
50 return;
51 }
48 if (instruction->value.special != ConstValSpecialRuntime) {52 if (instruction->value.special != ConstValSpecialRuntime) {
49 ir_print_const_value(irp, &instruction->value);53 ir_print_const_value(irp, &instruction->value);
50 } else {54 } else {
test/compile_errors.zig+22
...@@ -1,6 +1,28 @@...@@ -1,6 +1,28 @@
1const tests = @import("tests.zig");1const tests = @import("tests.zig");
22
3pub fn addCases(cases: *tests.CompileErrorContext) void {3pub 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
4 cases.add(26 cases.add(
5 "missing parameter name of generic function",27 "missing parameter name of generic function",
6 \\fn dump(var) void {}28 \\fn dump(var) void {}