Skip to content

Commit

Permalink
add compile error for ignoring return value of while loop bodies
Browse files Browse the repository at this point in the history
closes #1049
  • Loading branch information
andrewrk committed Jul 26, 2018
1 parent fd575fe commit 2cbad36
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/analyze.cpp
Expand Up @@ -4056,7 +4056,7 @@ void analyze_fn_ir(CodeGen *g, FnTableEntry *fn_table_entry, AstNode *return_typ
}

if (g->verbose_ir) {
fprintf(stderr, "{ // (analyzed)\n");
fprintf(stderr, "fn %s() { // (analyzed)\n", buf_ptr(&fn_table_entry->symbol_name));
ir_print(g, stderr, &fn_table_entry->analyzed_executable, 4);
fprintf(stderr, "}\n");
}
Expand Down
12 changes: 9 additions & 3 deletions src/ir.cpp
Expand Up @@ -5251,8 +5251,10 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
if (body_result == irb->codegen->invalid_instruction)
return body_result;

if (!instr_is_unreachable(body_result))
if (!instr_is_unreachable(body_result)) {
ir_mark_gen(ir_build_check_statement_is_void(irb, payload_scope, node->data.while_expr.body, body_result));
ir_mark_gen(ir_build_br(irb, payload_scope, node, continue_block, is_comptime));
}

if (continue_expr_node) {
ir_set_cursor_at_end_and_append_block(irb, continue_block);
Expand Down Expand Up @@ -5331,8 +5333,10 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
if (body_result == irb->codegen->invalid_instruction)
return body_result;

if (!instr_is_unreachable(body_result))
if (!instr_is_unreachable(body_result)) {
ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.while_expr.body, body_result));
ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime));
}

if (continue_expr_node) {
ir_set_cursor_at_end_and_append_block(irb, continue_block);
Expand Down Expand Up @@ -5392,8 +5396,10 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
if (body_result == irb->codegen->invalid_instruction)
return body_result;

if (!instr_is_unreachable(body_result))
if (!instr_is_unreachable(body_result)) {
ir_mark_gen(ir_build_check_statement_is_void(irb, scope, node->data.while_expr.body, body_result));
ir_mark_gen(ir_build_br(irb, scope, node, continue_block, is_comptime));
}

if (continue_expr_node) {
ir_set_cursor_at_end_and_append_block(irb, continue_block);
Expand Down
4 changes: 4 additions & 0 deletions src/ir_print.cpp
Expand Up @@ -45,6 +45,10 @@ static void ir_print_var_instruction(IrPrint *irp, IrInstruction *instruction) {
}

static void ir_print_other_instruction(IrPrint *irp, IrInstruction *instruction) {
if (instruction == nullptr) {
fprintf(irp->f, "(null)");
return;
}
if (instruction->value.special != ConstValSpecialRuntime) {
ir_print_const_value(irp, &instruction->value);
} else {
Expand Down
22 changes: 22 additions & 0 deletions test/compile_errors.zig
@@ -1,6 +1,28 @@
const tests = @import("tests.zig");

pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
"while loop body expression ignored",
\\fn returns() usize {
\\ return 2;
\\}
\\export fn f1() void {
\\ while (true) returns();
\\}
\\export fn f2() void {
\\ var x: ?i32 = null;
\\ while (x) |_| returns();
\\}
\\export fn f3() void {
\\ var x: error!i32 = error.Bad;
\\ while (x) |_| returns() else |_| unreachable;
\\}
,
".tmp_source.zig:5:25: error: expression value is ignored",
".tmp_source.zig:9:26: error: expression value is ignored",
".tmp_source.zig:13:26: error: expression value is ignored",
);

cases.add(
"missing parameter name of generic function",
\\fn dump(var) void {}
Expand Down

0 comments on commit 2cbad36

Please sign in to comment.