From c96131f30caaf6d7cd1d202891a28ee0df8b577e Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sun, 12 Jan 2020 15:04:43 +0100 Subject: [PATCH] Propagate errors in for loop bodies Closes #3819 --- src/ir.cpp | 2 ++ test/compile_errors.zig | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/src/ir.cpp b/src/ir.cpp index 9f45ff5b2f..340b27119a 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -7456,6 +7456,8 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo // it's actually in break statements, handled similarly to return statements. // That is why we set those values in loop_scope above and not in this ir_gen_node call. IrInstruction *body_result = ir_gen_node(irb, body_node, &loop_scope->base); + if (body_result == irb->codegen->invalid_instruction) + return irb->codegen->invalid_instruction; if (!instr_is_unreachable(body_result)) { ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.for_expr.body, body_result)); diff --git a/test/compile_errors.zig b/test/compile_errors.zig index f2111da9f9..bc140cb627 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -2,6 +2,15 @@ const tests = @import("tests.zig"); const builtin = @import("builtin"); pub fn addCases(cases: *tests.CompileErrorContext) void { + cases.addTest("errors in for loop bodies are propagated", + \\pub export fn entry() void { + \\ var arr: [100]u8 = undefined; + \\ for (arr) |bits| _ = @popCount(bits); + \\} + , &[_][]const u8{ + "tmp.zig:3:26: error: expected 2 arguments, found 1", + }); + cases.addTest("error in struct initializer doesn't crash the compiler", \\pub export fn entry() void { \\ const bitfield = struct {