Commit b38b967844

Andrew Kelley <andrew@ziglang.org>
2020-01-28 00:26:39
fix triple level result location with bitcast sandwich
...passed as tuple element
1 parent b96872e
Changed files (2)
src
test
stage1
behavior
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,
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)))});
+}