From b38b96784406c1d9e5f4246442f9414dba6812d2 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 27 Jan 2020 18:26:39 -0500 Subject: [PATCH] fix triple level result location with bitcast sandwich ...passed as tuple element --- src/ir.cpp | 16 ++++++++++++++-- test/stage1/behavior/bitcast.zig | 10 ++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/ir.cpp b/src/ir.cpp index 94d39b8cb6..7f995a4343 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -18505,6 +18505,7 @@ static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_i return bitcasted_value; } + bool parent_was_written = result_bit_cast->parent->written; IrInstGen *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_bit_cast->parent, dest_type, bitcasted_value, force_runtime, true); if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || @@ -18521,13 +18522,24 @@ static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_i return parent_result_loc; } - if ((err = type_resolve(ira->codegen, child_type, ResolveStatusAlignmentKnown))) { + if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) { return ira->codegen->invalid_inst_gen; } - if ((err = type_resolve(ira->codegen, value_type, ResolveStatusAlignmentKnown))) { + if ((err = type_resolve(ira->codegen, value_type, ResolveStatusSizeKnown))) { return ira->codegen->invalid_inst_gen; } + + if (child_type != ira->codegen->builtin_types.entry_var) { + if (type_size(ira->codegen, child_type) != type_size(ira->codegen, value_type)) { + // pointer cast won't work; we need a temporary location. + result_bit_cast->parent->written = parent_was_written; + result_loc->written = true; + result_loc->resolved_loc = ir_resolve_result(ira, suspend_source_instr, no_result_loc(), + value_type, bitcasted_value, force_runtime, true); + return result_loc->resolved_loc; + } + } uint64_t parent_ptr_align = 0; if (type_has_bits(value_type)) parent_ptr_align = get_ptr_align(ira->codegen, parent_ptr_type); ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value_type, diff --git a/test/stage1/behavior/bitcast.zig b/test/stage1/behavior/bitcast.zig index 9eefdb01cf..2cc1026354 100644 --- a/test/stage1/behavior/bitcast.zig +++ b/test/stage1/behavior/bitcast.zig @@ -177,3 +177,13 @@ test "bitcast passed as tuple element" { }; S.foo(.{@bitCast(f32, @as(u32, 0x414570A4))}); } + +test "triple level result location with bitcast sandwich passed as tuple element" { + const S = struct { + fn foo(args: var) void { + comptime expect(@TypeOf(args[0]) == f64); + expect(args[0] > 12.33 and args[0] < 12.35); + } + }; + S.foo(.{@as(f64, @bitCast(f32, @as(u32, 0x414570A4)))}); +}