diff --git a/src/ir.cpp b/src/ir.cpp index bd65e2d538..8887976942 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -9226,6 +9226,8 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP return ira->codegen->builtin_types.entry_invalid; } + bool all_stack_ptrs = (resolved_type->id == TypeTableEntryIdPointer); + // cast all values to the resolved type. however we can't put cast instructions in front of the phi instruction. // so we go back and insert the casts as the last instruction in the corresponding predecessor blocks, and // then make sure the branch instruction is preserved. @@ -9238,12 +9240,23 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP IrInstruction *casted_value = ir_implicit_cast(ira, new_value, resolved_type); new_incoming_values.items[i] = casted_value; predecessor->instruction_list.append(branch_instruction); + + if (all_stack_ptrs && (casted_value->value.special != ConstValSpecialRuntime || + casted_value->value.data.rh_ptr != RuntimeHintPtrStack)) + { + all_stack_ptrs = false; + } } ir_set_cursor_at_end(&ira->new_irb, cur_bb); - ir_build_phi_from(&ira->new_irb, &phi_instruction->base, new_incoming_blocks.length, + IrInstruction *result = ir_build_phi_from(&ira->new_irb, &phi_instruction->base, new_incoming_blocks.length, new_incoming_blocks.items, new_incoming_values.items); + if (all_stack_ptrs) { + assert(result->value.special == ConstValSpecialRuntime); + result->value.data.rh_ptr = RuntimeHintPtrStack; + } + return resolved_type; } diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 9f0b9de232..b9ab36c1af 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -1611,11 +1611,21 @@ pub fn addCases(cases: &tests.CompileErrorContext) { ".tmp_source.zig:3:5: error: cannot set section of external function 'foo'", ".tmp_source.zig:1:8: note: declared here"); - cases.add("returning address of local variable", + cases.add("returning address of local variable - simple", \\export fn foo() -> &i32 { \\ var a: i32 = undefined; \\ return &a; \\} , ".tmp_source.zig:3:13: error: function returns address of local variable"); + + cases.add("returning address of local variable - phi", + \\export fn foo(c: bool) -> &i32 { + \\ var a: i32 = undefined; + \\ var b: i32 = undefined; + \\ return if (c) &a else &b; + \\} + , + ".tmp_source.zig:4:12: error: function returns address of local variable"); + }