[clang] [TBAA] Handle bitfields when generating !tbaa.struct metadata. (PR #82922)

Eli Friedman via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 26 13:57:50 PST 2024


================
@@ -294,18 +297,49 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset,
         return false;
 
     const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+    const CGRecordLayout &CGRL = CGTypes.getCGRecordLayout(RD);
 
     unsigned idx = 0;
-    for (RecordDecl::field_iterator i = RD->field_begin(),
-         e = RD->field_end(); i != e; ++i, ++idx) {
-      if ((*i)->isZeroSize(Context) || (*i)->isUnnamedBitfield())
+    for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
+         i != e;) {
+      if ((*i)->isZeroSize(Context)) {
+        ++i;
+        ++idx;
         continue;
-      uint64_t Offset = BaseOffset +
-                        Layout.getFieldOffset(idx) / Context.getCharWidth();
+      }
+
+      uint64_t Offset =
+          BaseOffset + Layout.getFieldOffset(idx) / Context.getCharWidth();
       QualType FieldQTy = i->getType();
+      // Create a single field for consecutive named bitfields using char as
+      // base type.
+      if ((*i)->isBitField() && !(*i)->isUnnamedBitfield()) {
+        unsigned CurrentBitFieldSize = 0;
+        unsigned CurrentBitFieldOffset = CGRL.getBitFieldInfo(*i).Offset;
+        while (i != e && (*i)->isBitField() && !(*i)->isUnnamedBitfield()) {
+          const CGBitFieldInfo &Info = CGRL.getBitFieldInfo(*i);
+          if (CurrentBitFieldSize + CurrentBitFieldOffset != Info.Offset)
+            break;
+          CurrentBitFieldSize += Info.Size;
----------------
efriedma-quic wrote:

Can we pull the initial offset and total length of the whole run bitfields out of the CGBitFieldInfo, instead of trying to add up the sizes of the individual fields?  I think it should be StorageOffset/StorageSize.

https://github.com/llvm/llvm-project/pull/82922


More information about the cfe-commits mailing list