Skip to content

Commit

Permalink
Union is not properly zero-initialized #1194
Browse files Browse the repository at this point in the history
  • Loading branch information
lerno committed May 16, 2024
1 parent e36c696 commit 094c105
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 4 deletions.
1 change: 1 addition & 0 deletions releasenotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
- Generic modules parameterized with constants would sometimes get the wrong parameterized module name causing conversion errors #1192.
- Duplicate emit of expressions on negation would incorrectly compile negated macros.
- Casting a slice address to its pointer type should not compile #1193.
- Union is not properly zero-initialized with designated initializer #1194.

### Stdlib changes
- Add 'zstr' variants for `string::new_format` / `string::tformat`.
Expand Down
6 changes: 2 additions & 4 deletions src/compiler/llvm_codegen_expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -2124,14 +2124,12 @@ static inline void llvm_emit_initialize_reference_designated(GenContext *c, BEVa
llvm_emit_initialize_reference_designated_bitstruct(c, ref, type->decl, elements);
return;
}
// Getting ready to initialize, get the real type.
Type *real_type = type_lowering(ref->type);

// Make sure we have an address.
llvm_value_addr(c, ref);

// Clear the memory if not union.
if (real_type->type_kind != TYPE_UNION) llvm_store_zero(c, ref);
// Clear the memory
llvm_store_zero(c, ref);

// Now walk through the elements.
VECEACH(elements, i)
Expand Down
33 changes: 33 additions & 0 deletions test/test_suite/union/designated_union_zeroing.c3t
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// #target: macos-x64
module test;
union Rect {
struct { float[<2>] min, max; }
}

fn Rect test_rect(float[<2>] max) {
Rect rect = {.max = max};
assert(rect.min == {});
return rect;
}

/* #expect: test.ll

%Rect = type { %.anon }
%.anon = type { <2 x float>, <2 x float> }

define { double, double } @test.test_rect(double %0) #0 {
entry:
%max = alloca <2 x float>, align 8
%rect = alloca %Rect, align 8
store double %0, ptr %max, align 8
call void @llvm.memset.p0.i64(ptr align 8 %rect, i8 0, i64 16, i1 false)
%ptradd = getelementptr inbounds i8, ptr %rect, i64 8
%1 = load <2 x float>, ptr %max, align 8
store <2 x float> %1, ptr %ptradd, align 8
%2 = load <2 x float>, ptr %rect, align 8
%eq = fcmp oeq <2 x float> %2, zeroinitializer
%3 = call i1 @llvm.vector.reduce.and.v2i1(<2 x i1> %eq)
call void @llvm.assume(i1 %3)
%4 = load { double, double }, ptr %rect, align 8
ret { double, double } %4
}
1 change: 1 addition & 0 deletions test/test_suite/union/union_codegen_const.c3t
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// #target: macos-x64
module test;

union Foo
Expand Down
1 change: 1 addition & 0 deletions test/test_suite/union/union_codegen_empty.c3t
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// #target: macos-x64
union UnionA
{
int a;
Expand Down
1 change: 1 addition & 0 deletions test/test_suite/union/union_codegen_overwrite_call.c3t
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// #target: macos-x64
module test;

union UnionB
Expand Down

0 comments on commit 094c105

Please sign in to comment.