Commit 458afb0ef9

Andrew Kelley <superjoe30@gmail.com>
2017-04-28 05:40:43
phi instruction retains stack ptr hint
1 parent 2e512a0
Changed files (2)
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;
 }
 
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");
+
 }