From 556fcefed9645aa0a0a965ff8f22d8accdf9eefc Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Sun, 25 Feb 2024 13:23:17 +0000 Subject: [PATCH 1/7] [TBAA] Skip all bitfields when generating !tbaa.struct metadata. At the moment, clang generates what I believe are incorrect !tbaa.struct fields for named bitfields. At the moment, the base type size is used for named bifields (e.g. sizeof(int)) instead of the bifield width per field. This results in overalpping fields in !tbaa.struct metadata. This causes incorrect results when extracting individual copied fields from !tbaa.struct as in added in dc85719d5. This patch fixes that by skipping all bitfields, not only unnamed ones (note that CollectFields has a TODO to support bitfields). As bitfields specify their widths in bits, while !tbaa metadata uses bytes for sizes and offsets, I don't think we would be able to generate correct metadata for them in general. If this understanding is correct, I can also extend the verifier to check that !tbaa.struct fields aren't overlapping. Fixes https://github.com/llvm/llvm-project/issues/82586 --- clang/lib/CodeGen/CodeGenTBAA.cpp | 2 +- clang/test/CodeGen/tbaa-struct.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp index dc288bc3f6157..43a1aee3d7382 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.cpp +++ b/clang/lib/CodeGen/CodeGenTBAA.cpp @@ -298,7 +298,7 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset, 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()) + if ((*i)->isZeroSize(Context) || (*i)->isBitField()) continue; uint64_t Offset = BaseOffset + Layout.getFieldOffset(idx) / Context.getCharWidth(); diff --git a/clang/test/CodeGen/tbaa-struct.cpp b/clang/test/CodeGen/tbaa-struct.cpp index ff5521fcf3f60..17c9d6bf6a726 100644 --- a/clang/test/CodeGen/tbaa-struct.cpp +++ b/clang/test/CodeGen/tbaa-struct.cpp @@ -130,7 +130,7 @@ void copy8(NamedBitfields *a1, NamedBitfields *a2) { // CHECK-OLD: [[TS3]] = !{i64 0, i64 8, !{{.*}}, i64 0, i64 2, !{{.*}}, i64 4, i64 8, !{{.*}}} // CHECK-OLD: [[TS4]] = !{i64 0, i64 1, [[TAG_CHAR]], i64 1, i64 1, [[TAG_CHAR]], i64 2, i64 1, [[TAG_CHAR]]} // CHECK-OLD: [[TS5]] = !{i64 0, i64 1, [[TAG_CHAR]], i64 4, i64 1, [[TAG_CHAR]], i64 5, i64 1, [[TAG_CHAR]]} -// CHECK-OLD: [[TS6]] = !{i64 0, i64 4, [[TAG_INT]], i64 1, i64 4, [[TAG_INT]], i64 2, i64 1, [[TAG_CHAR]], i64 8, i64 8, [[TAG_DOUBLE:!.+]]} +// CHECK-OLD: [[TS6]] = !{i64 2, i64 1, [[TAG_CHAR]], i64 8, i64 8, [[TAG_DOUBLE:!.+]]} // CHECK-OLD: [[TAG_DOUBLE]] = !{[[DOUBLE:!.+]], [[DOUBLE]], i64 0} // CHECK-OLD [[DOUBLE]] = !{!"double", [[CHAR]], i64 0} From 32be3b7d944fc5da50add4b6fea551ba6c9d428c Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Mon, 26 Feb 2024 10:19:57 +0000 Subject: [PATCH 2/7] WIP use CGBitFieldInfo. --- clang/lib/CodeGen/CodeGenModule.cpp | 2 +- clang/lib/CodeGen/CodeGenTBAA.cpp | 33 +++++++++++++++++++++++------ clang/lib/CodeGen/CodeGenTBAA.h | 4 +++- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 95e457bef28ed..ed8db05572302 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -397,7 +397,7 @@ CodeGenModule::CodeGenModule(ASTContext &C, // Enable TBAA unless it's suppressed. ThreadSanitizer needs TBAA even at O0. if (LangOpts.Sanitize.has(SanitizerKind::Thread) || (!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0)) - TBAA.reset(new CodeGenTBAA(Context, TheModule, CodeGenOpts, getLangOpts(), + TBAA.reset(new CodeGenTBAA(Context, getTypes(), TheModule, CodeGenOpts, getLangOpts(), getCXXABI().getMangleContext())); // If debug info or coverage generation is enabled, create the CGDebugInfo diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp index 43a1aee3d7382..6a453bb114458 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.cpp +++ b/clang/lib/CodeGen/CodeGenTBAA.cpp @@ -14,6 +14,8 @@ // //===----------------------------------------------------------------------===// +#include "CGRecordLayout.h" +#include "CodeGenTypes.h" #include "CodeGenTBAA.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Attr.h" @@ -29,10 +31,10 @@ using namespace clang; using namespace CodeGen; -CodeGenTBAA::CodeGenTBAA(ASTContext &Ctx, llvm::Module &M, +CodeGenTBAA::CodeGenTBAA(ASTContext &Ctx, CodeGenTypes &CGTypes, llvm::Module &M, const CodeGenOptions &CGO, const LangOptions &Features, MangleContext &MContext) - : Context(Ctx), Module(M), CodeGenOpts(CGO), + : Context(Ctx), CGTypes(CGTypes), Module(M), CodeGenOpts(CGO), Features(Features), MContext(MContext), MDHelper(M.getContext()), Root(nullptr), Char(nullptr) {} @@ -294,18 +296,37 @@ 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)->isBitField()) + if ((*i)->isZeroSize(Context)) continue; + uint64_t Offset = BaseOffset + Layout.getFieldOffset(idx) / Context.getCharWidth(); QualType FieldQTy = i->getType(); - if (!CollectFields(Offset, FieldQTy, Fields, - MayAlias || TypeHasMayAlias(FieldQTy))) - return false; + if ((*i)->isBitField()) { + RecordDecl::field_iterator j = i; + unsigned CurrentBitFieldSize = 0; + while (j != e && (*j)->isBitField()) { + const CGBitFieldInfo &Info = CGRL.getBitFieldInfo(*j); + CurrentBitFieldSize += Info.Size; + j++; + } + uint64_t Offset = BaseOffset; + uint64_t Size = llvm::divideCeil(CurrentBitFieldSize , 8); + llvm::MDNode *TBAAType = getChar(); + llvm::MDNode *TBAATag = getAccessTagInfo(TBAAAccessInfo(TBAAType, Size)); + Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag)); + i = std::prev(j); + } else { + if (!CollectFields(Offset, FieldQTy, Fields, + MayAlias || TypeHasMayAlias(FieldQTy))) + return false; + + } } return true; } diff --git a/clang/lib/CodeGen/CodeGenTBAA.h b/clang/lib/CodeGen/CodeGenTBAA.h index a65963596fe9d..7e315c285be38 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.h +++ b/clang/lib/CodeGen/CodeGenTBAA.h @@ -29,6 +29,7 @@ namespace clang { class Type; namespace CodeGen { + class CodeGenTypes; // TBAAAccessKind - A kind of TBAA memory access descriptor. enum class TBAAAccessKind : unsigned { @@ -115,6 +116,7 @@ struct TBAAAccessInfo { /// while lowering AST types to LLVM types. class CodeGenTBAA { ASTContext &Context; + CodeGenTypes &CGTypes; llvm::Module &Module; const CodeGenOptions &CodeGenOpts; const LangOptions &Features; @@ -167,7 +169,7 @@ class CodeGenTBAA { llvm::MDNode *getBaseTypeInfoHelper(const Type *Ty); public: - CodeGenTBAA(ASTContext &Ctx, llvm::Module &M, const CodeGenOptions &CGO, + CodeGenTBAA(ASTContext &Ctx, CodeGenTypes &CGTypes, llvm::Module &M, const CodeGenOptions &CGO, const LangOptions &Features, MangleContext &MContext); ~CodeGenTBAA(); From 98b70456dd9c6177078027e3c86941b64a0fb72d Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Mon, 26 Feb 2024 11:53:05 +0000 Subject: [PATCH 3/7] Extra test. --- clang/test/CodeGen/tbaa-struct.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/clang/test/CodeGen/tbaa-struct.cpp b/clang/test/CodeGen/tbaa-struct.cpp index 17c9d6bf6a726..fa3718f4adcfa 100644 --- a/clang/test/CodeGen/tbaa-struct.cpp +++ b/clang/test/CodeGen/tbaa-struct.cpp @@ -109,14 +109,32 @@ struct NamedBitfields { double f3; }; -NamedBitfields g; - void copy8(NamedBitfields *a1, NamedBitfields *a2) { // CHECK-LABEL: _Z5copy8P14NamedBitfieldsS0_ // CHECK: tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 8 dereferenceable(16) %a1, ptr noundef nonnull align 8 dereferenceable(16) %a2, i64 16, i1 false), // CHECK-OLD-SAME: !tbaa.struct [[TS6:!.*]] // CHECK-NEW-SAME: !tbaa [[TAG_NamedBitfields:!.+]], !tbaa.struct *a1 = *a2; + a1->f0 =0; + a1->f2 =0; +} + +struct NamedBitfields2 { + char a, b, c; + signed f0 : 3; + unsigned f1 : 4; + char f2 : 7; + double f3; + unsigned f4 : 4; +}; + +void copy9(NamedBitfields2 *a1, NamedBitfields2 *a2) { +// CHECK-LABEL: _Z5copy8P14NamedBitfieldsS0_ +// CHECK: tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 8 dereferenceable(16) %a1, ptr noundef nonnull align 8 dereferenceable(16) %a2, i64 16, i1 false), +// CHECK-OLD-SAME: !tbaa.struct [[TS6:!.*]] +// CHECK-NEW-SAME: !tbaa [[TAG_NamedBitfields:!.+]], !tbaa.struct + *a1 = *a2; + a1->f0 =0; } // CHECK-OLD: [[TS]] = !{i64 0, i64 2, !{{.*}}, i64 4, i64 4, !{{.*}}, i64 8, i64 1, !{{.*}}, i64 12, i64 4, !{{.*}}} From e4e4614405506e5be5f668ce06c2a7373f8b052c Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Mon, 26 Feb 2024 12:02:06 +0000 Subject: [PATCH 4/7] fixup use bitfield info --- clang/lib/CodeGen/CodeGenTBAA.cpp | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp index 6a453bb114458..dbb58c235841b 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.cpp +++ b/clang/lib/CodeGen/CodeGenTBAA.cpp @@ -28,6 +28,7 @@ #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" +#include "llvm/Support/Debug.h" using namespace clang; using namespace CodeGen; @@ -300,33 +301,38 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset, unsigned idx = 0; for (RecordDecl::field_iterator i = RD->field_begin(), - e = RD->field_end(); i != e; ++i, ++idx) { - if ((*i)->isZeroSize(Context)) + e = RD->field_end(); i != e;) { + if ((*i)->isZeroSize(Context)) { + ++i; ++idx; continue; + } uint64_t Offset = BaseOffset + Layout.getFieldOffset(idx) / Context.getCharWidth(); QualType FieldQTy = i->getType(); - if ((*i)->isBitField()) { - RecordDecl::field_iterator j = i; + if ((*i)->isBitField() && !(*i)->isUnnamedBitfield()) { unsigned CurrentBitFieldSize = 0; - while (j != e && (*j)->isBitField()) { - const CGBitFieldInfo &Info = CGRL.getBitFieldInfo(*j); + unsigned CurrentBitFieldOffset = 0; + while (i != e && (*i)->isBitField() && !(*i)->isUnnamedBitfield()) { + const CGBitFieldInfo &Info = CGRL.getBitFieldInfo(*i); + if (CurrentBitFieldSize + CurrentBitFieldOffset != Info.Offset) + break; CurrentBitFieldSize += Info.Size; - j++; + CurrentBitFieldOffset = Info.Offset; + ++i; + ++idx; } - uint64_t Offset = BaseOffset; uint64_t Size = llvm::divideCeil(CurrentBitFieldSize , 8); llvm::MDNode *TBAAType = getChar(); llvm::MDNode *TBAATag = getAccessTagInfo(TBAAAccessInfo(TBAAType, Size)); Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag)); - i = std::prev(j); } else { if (!CollectFields(Offset, FieldQTy, Fields, MayAlias || TypeHasMayAlias(FieldQTy))) return false; - } + ++i; ++idx; + } } return true; } From a2dde72006fd44fa6ebf7f66f537e7d0d9c03fce Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Mon, 26 Feb 2024 12:41:32 +0000 Subject: [PATCH 5/7] !fixup --- clang/lib/CodeGen/CodeGenTBAA.cpp | 39 ++++++++++++++++++------------ clang/test/CodeGen/tbaa-struct.cpp | 24 ++---------------- 2 files changed, 25 insertions(+), 38 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp index dbb58c235841b..c300e7b20db72 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.cpp +++ b/clang/lib/CodeGen/CodeGenTBAA.cpp @@ -14,9 +14,9 @@ // //===----------------------------------------------------------------------===// +#include "CodeGenTBAA.h" #include "CGRecordLayout.h" #include "CodeGenTypes.h" -#include "CodeGenTBAA.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Attr.h" #include "clang/AST/Mangle.h" @@ -300,19 +300,22 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset, const CGRecordLayout &CGRL = CGTypes.getCGRecordLayout(RD); unsigned idx = 0; - for (RecordDecl::field_iterator i = RD->field_begin(), - e = RD->field_end(); i != e;) { + for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); + i != e;) { if ((*i)->isZeroSize(Context)) { - ++i; ++idx; + ++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 = 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) @@ -322,17 +325,21 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset, ++i; ++idx; } - uint64_t Size = llvm::divideCeil(CurrentBitFieldSize , 8); + uint64_t Size = + llvm::divideCeil(CurrentBitFieldSize, Context.getCharWidth()); llvm::MDNode *TBAAType = getChar(); - llvm::MDNode *TBAATag = getAccessTagInfo(TBAAAccessInfo(TBAAType, Size)); - Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag)); - } else { - if (!CollectFields(Offset, FieldQTy, Fields, - MayAlias || TypeHasMayAlias(FieldQTy))) - return false; - - ++i; ++idx; + llvm::MDNode *TBAATag = + getAccessTagInfo(TBAAAccessInfo(TBAAType, Size)); + Fields.push_back( + llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag)); + continue; } + if (!CollectFields(Offset, FieldQTy, Fields, + MayAlias || TypeHasMayAlias(FieldQTy))) + return false; + + ++i; + ++idx; } return true; } diff --git a/clang/test/CodeGen/tbaa-struct.cpp b/clang/test/CodeGen/tbaa-struct.cpp index 11491a2fcb594..854a86bc2cb01 100644 --- a/clang/test/CodeGen/tbaa-struct.cpp +++ b/clang/test/CodeGen/tbaa-struct.cpp @@ -115,26 +115,6 @@ void copy8(NamedBitfields *a1, NamedBitfields *a2) { // CHECK-OLD-SAME: !tbaa.struct [[TS6:!.*]] // CHECK-NEW-SAME: !tbaa [[TAG_NamedBitfields:!.+]], !tbaa.struct *a1 = *a2; - a1->f0 =0; - a1->f2 =0; -} - -struct NamedBitfields2 { - char a, b, c; - signed f0 : 3; - unsigned f1 : 4; - char f2 : 7; - double f3; - unsigned f4 : 4; -}; - -void copy9(NamedBitfields2 *a1, NamedBitfields2 *a2) { -// CHECK-LABEL: _Z5copy8P14NamedBitfieldsS0_ -// CHECK: tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 8 dereferenceable(16) %a1, ptr noundef nonnull align 8 dereferenceable(16) %a2, i64 16, i1 false), -// CHECK-OLD-SAME: !tbaa.struct [[TS6:!.*]] -// CHECK-NEW-SAME: !tbaa [[TAG_NamedBitfields:!.+]], !tbaa.struct - *a1 = *a2; - a1->f0 =0; } struct NamedBitfields2 { @@ -165,10 +145,10 @@ void copy9(NamedBitfields2 *a1, NamedBitfields2 *a2) { // CHECK-OLD: [[TS3]] = !{i64 0, i64 8, !{{.*}}, i64 0, i64 2, !{{.*}}, i64 4, i64 8, !{{.*}}} // CHECK-OLD: [[TS4]] = !{i64 0, i64 1, [[TAG_CHAR]], i64 1, i64 1, [[TAG_CHAR]], i64 2, i64 1, [[TAG_CHAR]]} // CHECK-OLD: [[TS5]] = !{i64 0, i64 1, [[TAG_CHAR]], i64 4, i64 1, [[TAG_CHAR]], i64 5, i64 1, [[TAG_CHAR]]} -// CHECK-OLD: [[TS6]] = !{i64 2, i64 1, [[TAG_CHAR]], i64 8, i64 8, [[TAG_DOUBLE:!.+]]} +// CHECK-OLD: [[TS6]] = !{i64 0, i64 2, [[TAG_CHAR]], i64 2, i64 1, [[TAG_CHAR]], i64 8, i64 8, [[TAG_DOUBLE:!.+]]} // CHECK-OLD: [[TAG_DOUBLE]] = !{[[DOUBLE:!.+]], [[DOUBLE]], i64 0} // CHECK-OLD [[DOUBLE]] = !{!"double", [[CHAR]], i64 0} -// CHECK-OLD: [[TS7]] = !{i64 0, i64 1, [[TAG_CHAR]], i64 1, i64 1, [[TAG_CHAR]], i64 2, i64 1, [[TAG_CHAR]], i64 3, i64 4, [[TAG_INT]], i64 3, i64 4, [[TAG_INT]], i64 4, i64 1, [[TAG_CHAR]], i64 8, i64 8, [[TAG_DOUBLE]], i64 16, i64 4, [[TAG_INT]]} +// CHECK-OLD: [[TS7]] = !{i64 0, i64 1, [[TAG_CHAR]], i64 1, i64 1, [[TAG_CHAR]], i64 2, i64 1, [[TAG_CHAR]], i64 3, i64 1, [[TAG_CHAR]], i64 4, i64 1, [[TAG_CHAR]], i64 8, i64 8, [[TAG_DOUBLE]], i64 16, i64 1, [[TAG_CHAR]]} // CHECK-NEW-DAG: [[TYPE_char:!.*]] = !{{{.*}}, i64 1, !"omnipotent char"} // CHECK-NEW-DAG: [[TAG_char]] = !{[[TYPE_char]], [[TYPE_char]], i64 0, i64 0} From f372ca9e8a80a58f7a73d4f7b26e643bd4760934 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Mon, 26 Feb 2024 22:36:18 +0000 Subject: [PATCH 6/7] Adjust --- clang/lib/CodeGen/CodeGenTBAA.cpp | 34 ++++++++++++------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp index c300e7b20db72..4031767633f29 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.cpp +++ b/clang/lib/CodeGen/CodeGenTBAA.cpp @@ -301,30 +301,22 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset, unsigned idx = 0; for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); - i != e;) { - if ((*i)->isZeroSize(Context)) { - ++i; - ++idx; - continue; - } + i != e; ++i, + ++idx +) { + if ((*i)->isZeroSize(Context)) + continue; 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; - CurrentBitFieldOffset = Info.Offset; - ++i; - ++idx; - } + if ((*i)->isBitField()) { + const CGBitFieldInfo &Info = CGRL.getBitFieldInfo(*i); + if (Info.Offset != 0) + continue; + unsigned CurrentBitFieldSize = Info.StorageSize; uint64_t Size = llvm::divideCeil(CurrentBitFieldSize, Context.getCharWidth()); llvm::MDNode *TBAAType = getChar(); @@ -334,12 +326,12 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset, llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag)); continue; } + + QualType FieldQTy = i->getType(); if (!CollectFields(Offset, FieldQTy, Fields, MayAlias || TypeHasMayAlias(FieldQTy))) return false; - ++i; - ++idx; } return true; } From 2f7f2d328e28f7d829ca76e84620356815d42937 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Tue, 27 Feb 2024 08:49:30 +0000 Subject: [PATCH 7/7] !fixup fix formatting, update new test. --- clang/lib/CodeGen/CodeGenModule.cpp | 4 ++-- clang/lib/CodeGen/CodeGenTBAA.cpp | 18 +++++++----------- clang/lib/CodeGen/CodeGenTBAA.h | 7 ++++--- clang/test/CodeGen/tbaa-struct.cpp | 2 +- 4 files changed, 14 insertions(+), 17 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 1c3654d341e41..d16d12fac8b03 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -397,8 +397,8 @@ CodeGenModule::CodeGenModule(ASTContext &C, // Enable TBAA unless it's suppressed. ThreadSanitizer needs TBAA even at O0. if (LangOpts.Sanitize.has(SanitizerKind::Thread) || (!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0)) - TBAA.reset(new CodeGenTBAA(Context, getTypes(), TheModule, CodeGenOpts, getLangOpts(), - getCXXABI().getMangleContext())); + TBAA.reset(new CodeGenTBAA(Context, getTypes(), TheModule, CodeGenOpts, + getLangOpts(), getCXXABI().getMangleContext())); // If debug info or coverage generation is enabled, create the CGDebugInfo // object. diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp index 4031767633f29..8a08161219397 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.cpp +++ b/clang/lib/CodeGen/CodeGenTBAA.cpp @@ -32,13 +32,12 @@ using namespace clang; using namespace CodeGen; -CodeGenTBAA::CodeGenTBAA(ASTContext &Ctx, CodeGenTypes &CGTypes, llvm::Module &M, - const CodeGenOptions &CGO, +CodeGenTBAA::CodeGenTBAA(ASTContext &Ctx, CodeGenTypes &CGTypes, + llvm::Module &M, const CodeGenOptions &CGO, const LangOptions &Features, MangleContext &MContext) - : Context(Ctx), CGTypes(CGTypes), Module(M), CodeGenOpts(CGO), - Features(Features), MContext(MContext), MDHelper(M.getContext()), - Root(nullptr), Char(nullptr) -{} + : Context(Ctx), CGTypes(CGTypes), Module(M), CodeGenOpts(CGO), + Features(Features), MContext(MContext), MDHelper(M.getContext()), + Root(nullptr), Char(nullptr) {} CodeGenTBAA::~CodeGenTBAA() { } @@ -301,11 +300,9 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset, unsigned idx = 0; for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); - i != e; ++i, - ++idx -) { + i != e; ++i, ++idx) { if ((*i)->isZeroSize(Context)) - continue; + continue; uint64_t Offset = BaseOffset + Layout.getFieldOffset(idx) / Context.getCharWidth(); @@ -331,7 +328,6 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset, if (!CollectFields(Offset, FieldQTy, Fields, MayAlias || TypeHasMayAlias(FieldQTy))) return false; - } return true; } diff --git a/clang/lib/CodeGen/CodeGenTBAA.h b/clang/lib/CodeGen/CodeGenTBAA.h index 7e315c285be38..aa6da2731a416 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.h +++ b/clang/lib/CodeGen/CodeGenTBAA.h @@ -29,7 +29,7 @@ namespace clang { class Type; namespace CodeGen { - class CodeGenTypes; +class CodeGenTypes; // TBAAAccessKind - A kind of TBAA memory access descriptor. enum class TBAAAccessKind : unsigned { @@ -169,8 +169,9 @@ class CodeGenTBAA { llvm::MDNode *getBaseTypeInfoHelper(const Type *Ty); public: - CodeGenTBAA(ASTContext &Ctx, CodeGenTypes &CGTypes, llvm::Module &M, const CodeGenOptions &CGO, - const LangOptions &Features, MangleContext &MContext); + CodeGenTBAA(ASTContext &Ctx, CodeGenTypes &CGTypes, llvm::Module &M, + const CodeGenOptions &CGO, const LangOptions &Features, + MangleContext &MContext); ~CodeGenTBAA(); /// getTypeInfo - Get metadata used to describe accesses to objects of the diff --git a/clang/test/CodeGen/tbaa-struct.cpp b/clang/test/CodeGen/tbaa-struct.cpp index 31c8e1de604cd..883c982be26c8 100644 --- a/clang/test/CodeGen/tbaa-struct.cpp +++ b/clang/test/CodeGen/tbaa-struct.cpp @@ -166,7 +166,7 @@ void copy10(NamedBitfields3 *a1, NamedBitfields3 *a2) { // CHECK-OLD: [[TAG_DOUBLE]] = !{[[DOUBLE:!.+]], [[DOUBLE]], i64 0} // CHECK-OLD [[DOUBLE]] = !{!"double", [[CHAR]], i64 0} // CHECK-OLD: [[TS7]] = !{i64 0, i64 1, [[TAG_CHAR]], i64 1, i64 1, [[TAG_CHAR]], i64 2, i64 1, [[TAG_CHAR]], i64 3, i64 1, [[TAG_CHAR]], i64 4, i64 1, [[TAG_CHAR]], i64 8, i64 8, [[TAG_DOUBLE]], i64 16, i64 1, [[TAG_CHAR]]} -// CHECK-OLD: [[TS8]] = !{i64 1, i64 4, [[TAG_INT]], i64 2, i64 4, [[TAG_INT]], i64 8, i64 8, [[TAG_DOUBLE]]} +// CHECK-OLD: [[TS8]] = !{i64 0, i64 4, [[TAG_CHAR]], i64 8, i64 8, [[TAG_DOUBLE]]} // CHECK-NEW-DAG: [[TYPE_char:!.*]] = !{{{.*}}, i64 1, !"omnipotent char"} // CHECK-NEW-DAG: [[TAG_char]] = !{[[TYPE_char]], [[TYPE_char]], i64 0, i64 0}