| author | |
| committer | |
| log | 7c236f6dd8194500f459b48621e2eb1997563caf |
| tree | c50e16f55a727f4f316ab2cda0e5cc97192edefc |
| parent | 9f92042da9a674bcef95f9ac18945371305e7f72 |
...in an if after an if in the 2nd switch prong
closes #3554 files changed, 47 insertions(+), 2 deletions(-)
src/all_types.hpp+1| ... | ... | @@ -1516,6 +1516,7 @@ struct VariableTableEntry { |
| 1516 | 1516 | size_t mem_slot_index; |
| 1517 | 1517 | size_t ref_count; |
| 1518 | 1518 | VarLinkage linkage; |
| 1519 | IrInstruction *decl_instruction; | |
| 1519 | 1520 | }; |
| 1520 | 1521 | |
| 1521 | 1522 | struct ErrorTableEntry { |
src/ir.cpp+8-2| ... | ... | @@ -2311,7 +2311,10 @@ static IrInstruction *ir_instruction_elemptr_get_dep(IrInstructionElemPtr *instr |
| 2311 | 2311 | } |
| 2312 | 2312 | |
| 2313 | 2313 | static 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 | } |
| 2316 | 2319 | |
| 2317 | 2320 | static 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 | 4649 | if (init_value == irb->codegen->invalid_instruction) |
| 4647 | 4650 | return init_value; |
| 4648 | 4651 | |
| 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 | } |
| 4651 | 4657 | |
| 4652 | 4658 | static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *node) { |
test/behavior.zig+1| ... | ... | @@ -24,6 +24,7 @@ comptime { |
| 24 | 24 | _ = @import("cases/namespace_depends_on_compile_var/index.zig"); |
| 25 | 25 | _ = @import("cases/null.zig"); |
| 26 | 26 | _ = @import("cases/pub_enum/index.zig"); |
| 27 | _ = @import("cases/ref_var_in_if_after_if_2nd_switch_prong.zig"); | |
| 27 | 28 | _ = @import("cases/sizeof_and_typeof.zig"); |
| 28 | 29 | _ = @import("cases/struct.zig"); |
| 29 | 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 @@ |
| 1 | const assert = @import("std").debug.assert; | |
| 2 | const mem = @import("std").mem; | |
| 3 | ||
| 4 | var ok: bool = false; | |
| 5 | test "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 | ||
| 14 | const Num = enum { | |
| 15 | One, | |
| 16 | Two, | |
| 17 | }; | |
| 18 | ||
| 19 | fn 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 | ||
| 34 | fn a(x: []const u8) { | |
| 35 | assert(mem.eql(u8, x, "aoeu")); | |
| 36 | ok = true; | |
| 37 | } |