phi instruction retains stack ptr hint
This commit is contained in:
parent
2e512a0e6e
commit
458afb0ef9
15
src/ir.cpp
15
src/ir.cpp
@ -9226,6 +9226,8 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP
|
|||||||
return ira->codegen->builtin_types.entry_invalid;
|
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.
|
// 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
|
// 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.
|
// 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);
|
IrInstruction *casted_value = ir_implicit_cast(ira, new_value, resolved_type);
|
||||||
new_incoming_values.items[i] = casted_value;
|
new_incoming_values.items[i] = casted_value;
|
||||||
predecessor->instruction_list.append(branch_instruction);
|
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_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);
|
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;
|
return resolved_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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:3:5: error: cannot set section of external function 'foo'",
|
||||||
".tmp_source.zig:1:8: note: declared here");
|
".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 {
|
\\export fn foo() -> &i32 {
|
||||||
\\ var a: i32 = undefined;
|
\\ var a: i32 = undefined;
|
||||||
\\ return &a;
|
\\ return &a;
|
||||||
\\}
|
\\}
|
||||||
,
|
,
|
||||||
".tmp_source.zig:3:13: error: function returns address of local variable");
|
".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");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user