zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

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:
Msrc/ir.cpp | 15++++++++++++++-
Mtest/compile_errors.zig | 12+++++++++++-
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"); + }