Skip to content

Conversation

@Andres-Salamanca
Copy link
Contributor

This PR fixes the outdated logic for accumulating bitfields in accumulateFields. The old approach remained after the algorithm was updated. A non-bitfield member would act as a barrier, causing accumulateBitFields to receive an incomplete range of fields. As a result, it failed to accumulate them properly when clipping was necessary.

For reference, in ClangIR we already handle this correctly:
https://github.com/llvm/clangir/blob/b647f4b97b1f936fd7700ec0fd0d896a12fe581b/clang/lib/CIR/CodeGen/CIRRecordLayoutBuilder.cpp#L711-L714

@llvmbot llvmbot added clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project labels Aug 1, 2025
@llvmbot
Copy link
Member

llvmbot commented Aug 1, 2025

@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clangir

Author: None (Andres-Salamanca)

Changes

This PR fixes the outdated logic for accumulating bitfields in accumulateFields. The old approach remained after the algorithm was updated. A non-bitfield member would act as a barrier, causing accumulateBitFields to receive an incomplete range of fields. As a result, it failed to accumulate them properly when clipping was necessary.

For reference, in ClangIR we already handle this correctly:
https://github.com/llvm/clangir/blob/b647f4b97b1f936fd7700ec0fd0d896a12fe581b/clang/lib/CIR/CodeGen/CIRRecordLayoutBuilder.cpp#L711-L714


Full diff: https://github.com/llvm/llvm-project/pull/151741.diff

2 Files Affected:

  • (modified) clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp (+1-5)
  • (modified) clang/test/CIR/CodeGen/bitfields.c (+11)
diff --git a/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp b/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp
index 0c8ff4bd807ad..ff9b38f79902c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp
@@ -499,11 +499,7 @@ void CIRRecordLowering::accumulateFields() {
                                   fieldEnd = recordDecl->field_end();
        field != fieldEnd;) {
     if (field->isBitField()) {
-      RecordDecl::field_iterator start = field;
-      // Iterate to gather the list of bitfields.
-      for (++field; field != fieldEnd && field->isBitField(); ++field)
-        ;
-      field = accumulateBitFields(start, field);
+      field = accumulateBitFields(field, fieldEnd);
       assert((field == fieldEnd || !field->isBitField()) &&
              "Failed to accumulate all the bitfields");
     } else if (!field->isZeroSize(astContext)) {
diff --git a/clang/test/CIR/CodeGen/bitfields.c b/clang/test/CIR/CodeGen/bitfields.c
index 869a7c98e2569..b2c7d1c0be926 100644
--- a/clang/test/CIR/CodeGen/bitfields.c
+++ b/clang/test/CIR/CodeGen/bitfields.c
@@ -71,12 +71,23 @@ typedef struct {
 // LLVM-DAG: %struct.U = type <{ i8, i8, i8, i8, i64 }>
 // OGCG-DAG: %struct.U = type <{ i8, i8, i8, i8, i64 }>
 
+typedef struct{
+    int a : 24;
+    char b;
+    int c: 30;
+} Clip;
+
+// CIR-DAG: !rec_Clip = !cir.record<struct "Clip" {!cir.array<!u8i x 3>, !s8i, !u32i}>
+// LLVM-DAG: %struct.Clip = type { [3 x i8], i8, i32 }
+// OGCG-DAG: %struct.Clip = type { [3 x i8], i8, i32 }
+
 void def() {
   A a;
   D d;
   S s;
   T t;
   U u;
+  Clip c;
 }
 
 int load_field(S* s) {

Copy link
Contributor

@andykaylor andykaylor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@Andres-Salamanca Andres-Salamanca merged commit 7e99271 into llvm:main Aug 2, 2025
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants