authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-05-02 12:59:09-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-05-02 12:59:09-04:00
log7c236f6dd8194500f459b48621e2eb1997563caf
treec50e16f55a727f4f316ab2cda0e5cc97192edefc
parent9f92042da9a674bcef95f9ac18945371305e7f72

fix compiler crash when referencing a variable...

...in an if after an if in the 2nd switch prong closes #355

4 files changed, 47 insertions(+), 2 deletions(-)

src/all_types.hpp+1
...@@ -1516,6 +1516,7 @@ struct VariableTableEntry {...@@ -1516,6 +1516,7 @@ struct VariableTableEntry {
1516 size_t mem_slot_index;1516 size_t mem_slot_index;
1517 size_t ref_count;1517 size_t ref_count;
1518 VarLinkage linkage;1518 VarLinkage linkage;
1519 IrInstruction *decl_instruction;
1519};1520};
15201521
1521struct ErrorTableEntry {1522struct ErrorTableEntry {
src/ir.cpp+8-2
...@@ -2311,7 +2311,10 @@ static IrInstruction *ir_instruction_elemptr_get_dep(IrInstructionElemPtr *instr...@@ -2311,7 +2311,10 @@ static IrInstruction *ir_instruction_elemptr_get_dep(IrInstructionElemPtr *instr
2311}2311}
23122312
2313static IrInstruction *ir_instruction_varptr_get_dep(IrInstructionVarPtr *instruction, size_t index) {2313static IrInstruction *ir_instruction_varptr_get_dep(IrInstructionVarPtr *instruction, size_t index) {
2314 return nullptr;2314 switch (index) {
2315 case 0: return instruction->var->decl_instruction; // can be null
2316 default: return nullptr;
2317 }
2315}2318}
23162319
2317static IrInstruction *ir_instruction_call_get_dep(IrInstructionCall *instruction, size_t index) {2320static IrInstruction *ir_instruction_call_get_dep(IrInstructionCall *instruction, size_t index) {
...@@ -4646,7 +4649,10 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod...@@ -4646,7 +4649,10 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
4646 if (init_value == irb->codegen->invalid_instruction)4649 if (init_value == irb->codegen->invalid_instruction)
4647 return init_value;4650 return init_value;
46484651
4649 return ir_build_var_decl(irb, scope, node, var, type_instruction, init_value);4652
4653 IrInstruction *result = ir_build_var_decl(irb, scope, node, var, type_instruction, init_value);
4654 var->decl_instruction = result;
4655 return result;
4650}4656}
46514657
4652static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *node) {4658static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *node) {
test/behavior.zig+1
...@@ -24,6 +24,7 @@ comptime {...@@ -24,6 +24,7 @@ comptime {
24 _ = @import("cases/namespace_depends_on_compile_var/index.zig");24 _ = @import("cases/namespace_depends_on_compile_var/index.zig");
25 _ = @import("cases/null.zig");25 _ = @import("cases/null.zig");
26 _ = @import("cases/pub_enum/index.zig");26 _ = @import("cases/pub_enum/index.zig");
27 _ = @import("cases/ref_var_in_if_after_if_2nd_switch_prong.zig");
27 _ = @import("cases/sizeof_and_typeof.zig");28 _ = @import("cases/sizeof_and_typeof.zig");
28 _ = @import("cases/struct.zig");29 _ = @import("cases/struct.zig");
29 _ = @import("cases/struct_contains_slice_of_itself.zig");30 _ = @import("cases/struct_contains_slice_of_itself.zig");
test/cases/ref_var_in_if_after_if_2nd_switch_prong.zig created+37
...@@ -0,0 +1,37 @@
1const assert = @import("std").debug.assert;
2const mem = @import("std").mem;
3
4var ok: bool = false;
5test "reference a variable in an if after an if in the 2nd switch prong" {
6 foo(true, Num.Two, false, "aoeu");
7 assert(!ok);
8 foo(false, Num.One, false, "aoeu");
9 assert(!ok);
10 foo(true, Num.One, false, "aoeu");
11 assert(ok);
12}
13
14const Num = enum {
15 One,
16 Two,
17};
18
19fn foo(c: bool, k: Num, c2: bool, b: []const u8) {
20 switch (k) {
21 Num.Two => {},
22 Num.One => {
23 if (c) {
24 const output_path = b;
25
26 if (c2) { }
27
28 a(output_path);
29 }
30 },
31 }
32}
33
34fn a(x: []const u8) {
35 assert(mem.eql(u8, x, "aoeu"));
36 ok = true;
37}