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

Reply via email to