Commit d18b5f8b53

LemonBoy <thatlemon@gmail.com>
2019-11-08 23:17:26
Fix initialization of union references
Fixes #3532
1 parent 8c80785
Changed files (4)
src/ir.cpp
@@ -18263,7 +18263,8 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
             if (!ptr_val)
                 return ira->codegen->invalid_instruction;
 
-            if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {
+            if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar &&
+                ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {
                 ConstExprValue *union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node);
                 if (union_val == nullptr)
                     return ira->codegen->invalid_instruction;
@@ -18295,7 +18296,6 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
 
                 ConstExprValue *payload_val = union_val->data.x_union.payload;
 
-
                 IrInstruction *result;
                 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) {
                     result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope,
src/ir_print.cpp
@@ -2549,3 +2549,18 @@ void ir_print_instruction(CodeGen *codegen, FILE *f, IrInstruction *instruction,
 
     ir_print_instruction(irp, instruction, false);
 }
+
+void ir_print_const_expr(CodeGen *codegen, FILE *f, ConstExprValue *value, int indent_size, IrPass pass) {
+    IrPrint ir_print = {};
+    IrPrint *irp = &ir_print;
+    irp->pass = pass;
+    irp->codegen = codegen;
+    irp->f = f;
+    irp->indent = indent_size;
+    irp->indent_size = indent_size;
+    irp->printed = {};
+    irp->printed.init(4);
+    irp->pending = {};
+
+    ir_print_const_value(irp, value);
+}
src/ir_print.hpp
@@ -14,6 +14,7 @@
 
 void ir_print(CodeGen *codegen, FILE *f, IrExecutable *executable, int indent_size, IrPass pass);
 void ir_print_instruction(CodeGen *codegen, FILE *f, IrInstruction *instruction, int indent_size, IrPass pass);
+void ir_print_const_expr(CodeGen *codegen, FILE *f, ConstExprValue *value, int indent_size, IrPass pass);
 
 const char* ir_instruction_type_str(IrInstructionId id);
 
test/stage1/behavior/union.zig
@@ -535,3 +535,17 @@ test "global union with single field is correctly initialized" {
     };
     expect(glbl.f.x == 123);
 }
+
+pub const FooUnion = union(enum) {
+    U0: usize,
+    U1: u8,
+};
+
+var glbl_array: [2]FooUnion = undefined;
+
+test "initialize global array of union" {
+    glbl_array[1] = FooUnion{ .U1 = 2 };
+    glbl_array[0] = FooUnion{ .U0 = 1 };
+    expect(glbl_array[0].U0 == 1);
+    expect(glbl_array[1].U1 == 2);
+}