| 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,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 | }; |
| 1520 | 1521 | ||
| 1521 | struct ErrorTableEntry { | 1522 | struct 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 | } |
| 2312 | 2312 | ||
| 2313 | static IrInstruction *ir_instruction_varptr_get_dep(IrInstructionVarPtr *instruction, size_t index) { | 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 | static IrInstruction *ir_instruction_call_get_dep(IrInstructionCall *instruction, size_t index) { | 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,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; |
| 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 | static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *node) { | 4658 | static 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 @@ | ||
| 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 | } | ||