r180038 - TBAA: make sure zero-length bitfield works for tbaa.struct and path-aware tbaa

Manman Ren mren at apple.com
Mon Apr 22 12:50:08 PDT 2013


Author: mren
Date: Mon Apr 22 14:50:07 2013
New Revision: 180038

URL: http://llvm.org/viewvc/llvm-project?rev=180038&view=rev
Log:
TBAA: make sure zero-length bitfield works for tbaa.struct and path-aware tbaa

For ms structs, zero-length bitfields following non-bitfield members are
completely ignored, we should not increase the field index.
Before the fix, we will have an assertion failure.

Modified:
    cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp
    cfe/trunk/test/CodeGen/tbaa-struct.cpp
    cfe/trunk/test/CodeGen/tbaa.cpp

Modified: cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp?rev=180038&r1=180037&r2=180038&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp Mon Apr 22 14:50:07 2013
@@ -204,8 +204,18 @@ CodeGenTBAA::CollectFields(uint64_t Base
     const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
 
     unsigned idx = 0;
+    const FieldDecl *LastFD = 0;
+    bool IsMsStruct = RD->isMsStruct(Context);
     for (RecordDecl::field_iterator i = RD->field_begin(),
          e = RD->field_end(); i != e; ++i, ++idx) {
+      if (IsMsStruct) {
+        // Zero-length bitfields following non-bitfield members are ignored.
+        if (Context.ZeroBitfieldFollowsNonBitfield(*i, LastFD)) {
+          --idx;
+          continue;
+        }
+        LastFD = *i;
+      }
       uint64_t Offset = BaseOffset +
                         Layout.getFieldOffset(idx) / Context.getCharWidth();
       QualType FieldQTy = i->getType();
@@ -220,7 +230,9 @@ CodeGenTBAA::CollectFields(uint64_t Base
   uint64_t Offset = BaseOffset;
   uint64_t Size = Context.getTypeSizeInChars(QTy).getQuantity();
   llvm::MDNode *TBAAInfo = MayAlias ? getChar() : getTBAAInfo(QTy);
-  Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size, TBAAInfo));
+  llvm::MDNode *TBAATag = CodeGenOpts.StructPathTBAA ?
+                          getTBAAScalarTagInfo(TBAAInfo) : TBAAInfo;
+  Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag));
   return true;
 }
 
@@ -265,8 +277,19 @@ CodeGenTBAA::getTBAAStructTypeInfo(QualT
     const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
     SmallVector <std::pair<uint64_t, llvm::MDNode*>, 4> Fields;
     unsigned idx = 0;
+    const FieldDecl *LastFD = 0;
+    bool IsMsStruct = RD->isMsStruct(Context);
     for (RecordDecl::field_iterator i = RD->field_begin(),
          e = RD->field_end(); i != e; ++i, ++idx) {
+      if (IsMsStruct) {
+        // Zero-length bitfields following non-bitfield members are ignored.
+        if (Context.ZeroBitfieldFollowsNonBitfield(*i, LastFD)) {
+          --idx;
+          continue;
+        }
+        LastFD = *i;
+      }
+
       QualType FieldQTy = i->getType();
       llvm::MDNode *FieldNode;
       if (isTBAAPathStruct(FieldQTy))

Modified: cfe/trunk/test/CodeGen/tbaa-struct.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/tbaa-struct.cpp?rev=180038&r1=180037&r2=180038&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/tbaa-struct.cpp (original)
+++ cfe/trunk/test/CodeGen/tbaa-struct.cpp Mon Apr 22 14:50:07 2013
@@ -39,8 +39,36 @@ void copy3 (T1 *a, T1 *b) {
 
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i[[P]](i8* %{{.*}}, i8* %{{.*}}, i[[P]] 12, i32 4, i1 false), !tbaa.struct [[TS3:!.*]]
 
+// Make sure that zero-length bitfield works.
+#define ATTR __attribute__ ((ms_struct))
+struct five {
+  char a;
+  int :0;        /* ignored; prior field is not a bitfield. */
+  char b;
+  char c;
+} ATTR;
+void copy4(struct five *a, struct five *b) {
+  *a = *b;
+}
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i[[P]](i8* %{{.*}}, i8* %{{.*}}, i[[P]] 3, i32 1, i1 false), !tbaa.struct [[TS4:!.*]]
+
+struct six {
+  char a;
+  int :0;
+  char b;
+  char c;
+};
+void copy5(struct six *a, struct six *b) {
+  *a = *b;
+}
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i[[P]](i8* %{{.*}}, i8* %{{.*}}, i[[P]] 6, i32 1, i1 false), !tbaa.struct [[TS5:!.*]]
+
 // CHECK: [[TS]] = metadata !{i64 0, i64 2, metadata !{{.*}}, i64 4, i64 4, metadata !{{.*}}, i64 8, i64 1, metadata !{{.*}}, i64 12, i64 4, metadata !{{.*}}}
+// CHECK: [[CHAR:!.*]] = metadata !{metadata !"omnipotent char", metadata !{{.*}}}
+// CHECK: [[INT:!.*]] = metadata !{metadata !"int", metadata [[CHAR]]}
 // (offset, size) = (0,1) char; (4,2) short; (8,4) int; (12,1) char; (16,4) int; (20,4) int
 // CHECK: [[TS2]] = metadata !{i64 0, i64 1, metadata !{{.*}}, i64 4, i64 2, metadata !{{.*}}, i64 8, i64 4, metadata !{{.*}}, i64 12, i64 1, metadata !{{.*}}, i64 16, i64 4, metadata {{.*}}, i64 20, i64 4, metadata {{.*}}}
 // (offset, size) = (0,8) char; (0,2) char; (4,8) char
 // CHECK: [[TS3]] = metadata !{i64 0, i64 8, metadata !{{.*}}, i64 0, i64 2, metadata !{{.*}}, i64 4, i64 8, metadata !{{.*}}}
+// CHECK: [[TS4]] = metadata !{i64 0, i64 1, metadata [[CHAR]], i64 1, i64 1, metadata [[CHAR]], i64 2, i64 1, metadata [[CHAR]]}
+// CHECK: [[TS5]] = metadata !{i64 0, i64 1, metadata [[CHAR]], i64 4, i64 4, metadata [[INT]], i64 4, i64 1, metadata [[CHAR]], i64 5, i64 1, metadata [[CHAR]]}

Modified: cfe/trunk/test/CodeGen/tbaa.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/tbaa.cpp?rev=180038&r1=180037&r2=180038&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/tbaa.cpp (original)
+++ cfe/trunk/test/CodeGen/tbaa.cpp Mon Apr 22 14:50:07 2013
@@ -192,6 +192,36 @@ uint32_t g12(StructC *C, StructD *D, uin
   return b1->a.f32;
 }
 
+// Make sure that zero-length bitfield works.
+#define ATTR __attribute__ ((ms_struct))
+struct five {
+  char a;
+  int :0;        /* ignored; prior field is not a bitfield. */
+  char b;
+  char c;
+} ATTR;
+char g13(struct five *a, struct five *b) {
+  return a->b;
+// CHECK: define signext i8 @{{.*}}(
+// CHECK: load i8* %{{.*}}, align 1, !tbaa !1
+// PATH: define signext i8 @{{.*}}(
+// PATH: load i8* %{{.*}}, align 1, !tbaa [[TAG_five_b:!.*]]
+}
+
+struct six {
+  char a;
+  int :0;
+  char b;
+  char c;
+};
+char g14(struct six *a, struct six *b) {
+// CHECK: define signext i8 @{{.*}}(
+// CHECK: load i8* %{{.*}}, align 1, !tbaa !1
+// PATH: define signext i8 @{{.*}}(
+// PATH: load i8* %{{.*}}, align 1, !tbaa [[TAG_six_b:!.*]]
+  return a->b;
+}
+
 // CHECK: !1 = metadata !{metadata !"omnipotent char", metadata !2}
 // CHECK: !2 = metadata !{metadata !"Simple C/C++ TBAA"}
 // CHECK: !4 = metadata !{metadata !"int", metadata !1}
@@ -219,3 +249,7 @@ uint32_t g12(StructC *C, StructD *D, uin
 // PATH: [[TYPE_C]] = metadata !{metadata !"_ZTS7StructC", i64 0, metadata [[TYPE_SHORT]], i64 4, metadata [[TYPE_B]], i64 28, metadata [[TYPE_INT]]}
 // PATH: [[TAG_D_b_a_f32]] = metadata !{metadata [[TYPE_D:!.*]], metadata [[TYPE_INT]], i64 12}
 // PATH: [[TYPE_D]] = metadata !{metadata !"_ZTS7StructD", i64 0, metadata [[TYPE_SHORT]], i64 4, metadata [[TYPE_B]], i64 28, metadata [[TYPE_INT]], i64 32, metadata [[TYPE_CHAR]]}
+// PATH: [[TAG_five_b]] = metadata !{metadata [[TYPE_five:!.*]], metadata [[TYPE_CHAR]], i64 1}
+// PATH: [[TYPE_five]] = metadata !{metadata !"_ZTS4five", i64 0, metadata [[TYPE_CHAR]], i64 1, metadata [[TYPE_CHAR]], i64 2, metadata [[TYPE_CHAR]]}
+// PATH: [[TAG_six_b]] = metadata !{metadata [[TYPE_six:!.*]], metadata [[TYPE_CHAR]], i64 4}
+// PATH: [[TYPE_six]] = metadata !{metadata !"_ZTS3six", i64 0, metadata [[TYPE_CHAR]], i64 4, metadata [[TYPE_INT]], i64 4, metadata [[TYPE_CHAR]], i64 5, metadata [[TYPE_CHAR]]}





More information about the cfe-commits mailing list