commit 458afb0ef9634b6a0480bcb6e07a92cd9a330d84 (tree)
parent 2e512a0e6e81532b62ddb7fdafdcd28926690eaa
Author: Andrew Kelley <superjoe30@gmail.com>
Date: Thu, 27 Apr 2017 23:40:43 -0400
phi instruction retains stack ptr hint
Diffstat:
2 files changed, 25 insertions(+), 2 deletions(-)
diff --git 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
@@ -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");
+
}