From 14022e45da444395f1e4174c56dbda8eb40c018f Mon Sep 17 00:00:00 2001 From: gitoleg Date: Wed, 17 Apr 2024 17:28:28 +0300 Subject: [PATCH] [CIR][Codegen] fix union init --- clang/lib/CIR/CodeGen/CIRGenExprConst.cpp | 6 +++++- clang/test/CIR/CodeGen/union.cpp | 13 +++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConst.cpp b/clang/lib/CIR/CodeGen/CIRGenExprConst.cpp index 8c527c2072bd..046c1d9aad15 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprConst.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprConst.cpp @@ -380,7 +380,11 @@ mlir::Attribute ConstantAggregateBuilder::buildFrom( NaturalLayout = false; Packed = true; } else if (DesiredSize > AlignedSize) { - llvm_unreachable("NYI"); + // The natural layout would be too small. Add padding to fix it. (This + // is ignored if we choose a packed layout.) + UnpackedElemStorage.assign(Elems.begin(), Elems.end()); + UnpackedElemStorage.push_back(Utils.getPadding(DesiredSize - Size)); + UnpackedElems = UnpackedElemStorage; } // If we don't have a natural layout, insert padding as necessary. diff --git a/clang/test/CIR/CodeGen/union.cpp b/clang/test/CIR/CodeGen/union.cpp index 2f90229eb6a7..49e41be613fd 100644 --- a/clang/test/CIR/CodeGen/union.cpp +++ b/clang/test/CIR/CodeGen/union.cpp @@ -76,3 +76,16 @@ void shouldGenerateUnionAccess(union U u) { u.d; // CHECK: %[[#BASE:]] = cir.get_member %0[4] {name = "d"} : !cir.ptr -> !cir.ptr } + +typedef union { + short a; + int b; +} A; + +void noCrushOnDifferentSizes() { + A a = {0}; + // CHECK: %[[#TMP0:]] = cir.alloca !ty_22A22, cir.ptr , ["a"] {alignment = 4 : i64} + // CHECK: %[[#TMP1:]] = cir.cast(bitcast, %[[#TMP0]] : !cir.ptr), !cir.ptr + // CHECK: %[[#TMP2:]] = cir.const(#cir.zero : !ty_anon_struct) : !ty_anon_struct + // CHECK: cir.store %[[#TMP2]], %[[#TMP1]] : !ty_anon_struct, cir.ptr +} \ No newline at end of file