diff options
author | Manman Ren <mren@apple.com> | 2013-04-22 19:50:07 +0000 |
---|---|---|
committer | Manman Ren <mren@apple.com> | 2013-04-22 19:50:07 +0000 |
commit | c7f2bfb4a2dcda757619356a28cb633711a6548c (patch) | |
tree | 84f2b96f3c8e2fce4d3214bf06942a3291b0ed4d | |
parent | 1e7ca6211c77208c8a339c2a26e612be81c70ec5 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@180038 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CodeGenTBAA.cpp | 25 | ||||
-rw-r--r-- | test/CodeGen/tbaa-struct.cpp | 28 | ||||
-rw-r--r-- | test/CodeGen/tbaa.cpp | 34 |
3 files changed, 86 insertions, 1 deletions
diff --git a/lib/CodeGen/CodeGenTBAA.cpp b/lib/CodeGen/CodeGenTBAA.cpp index bb1ebda908..95b9714c34 100644 --- a/lib/CodeGen/CodeGenTBAA.cpp +++ b/lib/CodeGen/CodeGenTBAA.cpp @@ -204,8 +204,18 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset, 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 BaseOffset, 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(QualType QTy) { 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)) diff --git a/test/CodeGen/tbaa-struct.cpp b/test/CodeGen/tbaa-struct.cpp index 12a6f4de82..3a93d75156 100644 --- a/test/CodeGen/tbaa-struct.cpp +++ b/test/CodeGen/tbaa-struct.cpp @@ -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]]} diff --git a/test/CodeGen/tbaa.cpp b/test/CodeGen/tbaa.cpp index c256b4af80..439fd20086 100644 --- a/test/CodeGen/tbaa.cpp +++ b/test/CodeGen/tbaa.cpp @@ -192,6 +192,36 @@ uint32_t g12(StructC *C, StructD *D, uint64_t count) { 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, uint64_t count) { // 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]]} |