https://github.com/spall created https://github.com/llvm/llvm-project/pull/159212
In HLSL Init List code avoid initializing unnamed bitfields and avoid initializing using unnamed bit fields. Add tests. Closes #157922 >From 323df6bb7b79839f2a88d06293ff7c955182cd86 Mon Sep 17 00:00:00 2001 From: Sarah Spall <sarahsp...@microsoft.com> Date: Tue, 16 Sep 2025 16:39:14 -0700 Subject: [PATCH] avoid unnamed bit fields when initializing --- clang/lib/Sema/SemaHLSL.cpp | 8 ++++-- .../CodeGenHLSL/BasicFeatures/InitLists.hlsl | 26 +++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 983efaf798b87..336240a5d193e 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -3326,7 +3326,8 @@ static void BuildFlattenedTypeList(QualType BaseTy, llvm::SmallVector<QualType, 16> FieldTypes; for (const auto *FD : RD->fields()) - FieldTypes.push_back(FD->getType()); + if (!FD->isUnnamedBitField()) + FieldTypes.push_back(FD->getType()); // Reverse the newly added sub-range. std::reverse(FieldTypes.begin(), FieldTypes.end()); llvm::append_range(WorkList, FieldTypes); @@ -4171,6 +4172,8 @@ class InitListTransformer { while (!RecordDecls.empty()) { CXXRecordDecl *RD = RecordDecls.pop_back_val(); for (auto *FD : RD->fields()) { + if (FD->isUnnamedBitField()) + continue; DeclAccessPair Found = DeclAccessPair::make(FD, FD->getAccess()); DeclarationNameInfo NameInfo(FD->getDeclName(), E->getBeginLoc()); ExprResult Res = S.BuildFieldReferenceExpr( @@ -4220,7 +4223,8 @@ class InitListTransformer { while (!RecordDecls.empty()) { CXXRecordDecl *RD = RecordDecls.pop_back_val(); for (auto *FD : RD->fields()) - Inits.push_back(generateInitListsImpl(FD->getType())); + if (!FD->isUnnamedBitField()) + Inits.push_back(generateInitListsImpl(FD->getType())); } } auto *NewInit = new (Ctx) InitListExpr(Ctx, Inits.front()->getBeginLoc(), diff --git a/clang/test/CodeGenHLSL/BasicFeatures/InitLists.hlsl b/clang/test/CodeGenHLSL/BasicFeatures/InitLists.hlsl index c30c640519cda..5a5c45f686956 100644 --- a/clang/test/CodeGenHLSL/BasicFeatures/InitLists.hlsl +++ b/clang/test/CodeGenHLSL/BasicFeatures/InitLists.hlsl @@ -45,6 +45,11 @@ struct SlicyBits { int W : 8; }; +struct Unnamed { + int A; + int : 8; +}; + // Case 1: Extraneous braces get ignored in literal instantiation. // CHECK-LABEL: define hidden void @_Z5case1v( // CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_TWOFLOATS:%.*]]) align 1 [[AGG_RESULT:%.*]]) #[[ATTR0:[0-9]+]] { @@ -959,3 +964,24 @@ int case17Helper(int x) { void case17() { int2 X = {case17Helper(0), case17Helper(1)}; } + +// InitList with Struct with unnamed bitfield on LHS +// CHECK-LABEL: case18 +// CHECK: [[U:%.*]] = alloca %struct.Unnamed, align 1 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[U]], ptr align 1 {{.*}}, i32 5, i1 false) +void case18() { + Unnamed U = {1}; +} + +// InitList with Struct with unnamed bitfield on RHS +// CHECK-LABEL: case19 +// CHECK: [[TI:%.*]] = alloca %struct.TwoInts, align 1 +// CHECK-NEXT: [[Z:%.*]] = getelementptr inbounds nuw %struct.TwoInts, ptr [[TI]], i32 0, i32 0 +// CHECK-NEXT: [[A:%.*]] = getelementptr inbounds nuw %struct.Unnamed, ptr %U, i32 0, i32 0 +// CHECK-NEXT: [[L:%.*]] = load i32, ptr [[A]], align 1 +// CHECK-NEXT: store i32 [[L]], ptr [[Z]], align 1 +// CHECK-NEXT: [[W:%.*]] = getelementptr inbounds nuw %struct.TwoInts, ptr [[TI]], i32 0, i32 1 +// CHECK-NEXT: store i32 1, ptr [[W]], align 1 +void case19(Unnamed U) { + TwoInts TI = {U, 1}; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits