authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-10-19 16:54:49+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-10-19 13:47:49-04:00
logbab93e75611de79a1a1e898b0c9e45905817189f
tree9af97dc0971ee3849b99fd7ab7e9610e492c10ff
parent63dfca97159fd66563693039606c0bca30aa1f85

Fix crash when generating constant unions with single field


2 files changed, 21 insertions(+), 2 deletions(-)

src/codegen.cpp+7-2
...@@ -6355,12 +6355,17 @@ static LLVMValueRef gen_const_ptr_union_recursive(CodeGen *g, ConstExprValue *un...@@ -6355,12 +6355,17 @@ static LLVMValueRef gen_const_ptr_union_recursive(CodeGen *g, ConstExprValue *un
6355 ConstParent *parent = &union_const_val->parent;6355 ConstParent *parent = &union_const_val->parent;
6356 LLVMValueRef base_ptr = gen_parent_ptr(g, union_const_val, parent);6356 LLVMValueRef base_ptr = gen_parent_ptr(g, union_const_val, parent);
63576357
6358 // Slot in the structure where the payload is stored, if equal to SIZE_MAX
6359 // the union has no tag and a single field and is collapsed into the field
6360 // itself
6361 size_t union_payload_index = union_const_val->type->data.unionation.gen_union_index;
6362
6358 ZigType *u32 = g->builtin_types.entry_u32;6363 ZigType *u32 = g->builtin_types.entry_u32;
6359 LLVMValueRef indices[] = {6364 LLVMValueRef indices[] = {
6360 LLVMConstNull(get_llvm_type(g, u32)),6365 LLVMConstNull(get_llvm_type(g, u32)),
6361 LLVMConstInt(get_llvm_type(g, u32), 0, false), // TODO test const union with more aligned tag type than payload6366 LLVMConstInt(get_llvm_type(g, u32), union_payload_index, false),
6362 };6367 };
6363 return LLVMConstInBoundsGEP(base_ptr, indices, 2);6368 return LLVMConstInBoundsGEP(base_ptr, indices, (union_payload_index != SIZE_MAX) ? 2 : 1);
6364}6369}
63656370
6366static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, ConstExprValue *const_val) {6371static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, ConstExprValue *const_val) {
test/stage1/behavior/union.zig+14
...@@ -521,3 +521,17 @@ test "extern union doesn't trigger field check at comptime" {...@@ -521,3 +521,17 @@ test "extern union doesn't trigger field check at comptime" {
521 const x = U{ .x = 0x55AAAA55 };521 const x = U{ .x = 0x55AAAA55 };
522 comptime expect(x.y == 0x55);522 comptime expect(x.y == 0x55);
523}523}
524
525const Foo1 = union(enum) {
526 f: struct {
527 x: usize,
528 },
529};
530var glbl: Foo1 = undefined;
531
532test "global union with single field is correctly initialized" {
533 glbl = Foo1{
534 .f = @memberType(Foo1, 0){ .x = 123 },
535 };
536 expect(glbl.f.x == 123);
537}