Skip to content

Commit 643bc6b

Browse files
committed
[TBAA] Handle bitfields when generating !tbaa.struct metadata. (llvm#82922)
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 dc85719. This patch fixes that by skipping by combining adjacent bitfields in fields with correct sizes. Fixes llvm#82586 (cherry-picked from d2a9df2)
1 parent b60e76e commit 643bc6b

File tree

4 files changed

+43
-18
lines changed

4 files changed

+43
-18
lines changed

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -393,8 +393,8 @@ CodeGenModule::CodeGenModule(ASTContext &C,
393393
// Enable TBAA unless it's suppressed. ThreadSanitizer needs TBAA even at O0.
394394
if (LangOpts.Sanitize.has(SanitizerKind::Thread) ||
395395
(!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0))
396-
TBAA.reset(new CodeGenTBAA(Context, TheModule, CodeGenOpts, getLangOpts(),
397-
getCXXABI().getMangleContext()));
396+
TBAA.reset(new CodeGenTBAA(Context, getTypes(), TheModule, CodeGenOpts,
397+
getLangOpts(), getCXXABI().getMangleContext()));
398398

399399
// If debug info or coverage generation is enabled, create the CGDebugInfo
400400
// object.

clang/lib/CodeGen/CodeGenTBAA.cpp

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
//===----------------------------------------------------------------------===//
1616

1717
#include "CodeGenTBAA.h"
18+
#include "CGRecordLayout.h"
19+
#include "CodeGenTypes.h"
1820
#include "clang/AST/ASTContext.h"
1921
#include "clang/AST/Attr.h"
2022
#include "clang/AST/Mangle.h"
@@ -26,16 +28,16 @@
2628
#include "llvm/IR/Metadata.h"
2729
#include "llvm/IR/Module.h"
2830
#include "llvm/IR/Type.h"
31+
#include "llvm/Support/Debug.h"
2932
using namespace clang;
3033
using namespace CodeGen;
3134

32-
CodeGenTBAA::CodeGenTBAA(ASTContext &Ctx, llvm::Module &M,
33-
const CodeGenOptions &CGO,
35+
CodeGenTBAA::CodeGenTBAA(ASTContext &Ctx, CodeGenTypes &CGTypes,
36+
llvm::Module &M, const CodeGenOptions &CGO,
3437
const LangOptions &Features, MangleContext &MContext)
35-
: Context(Ctx), Module(M), CodeGenOpts(CGO),
36-
Features(Features), MContext(MContext), MDHelper(M.getContext()),
37-
Root(nullptr), Char(nullptr)
38-
{}
38+
: Context(Ctx), CGTypes(CGTypes), Module(M), CodeGenOpts(CGO),
39+
Features(Features), MContext(MContext), MDHelper(M.getContext()),
40+
Root(nullptr), Char(nullptr) {}
3941

4042
CodeGenTBAA::~CodeGenTBAA() {
4143
}
@@ -291,14 +293,34 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset,
291293
return false;
292294

293295
const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
296+
const CGRecordLayout &CGRL = CGTypes.getCGRecordLayout(RD);
294297

295298
unsigned idx = 0;
296-
for (RecordDecl::field_iterator i = RD->field_begin(),
297-
e = RD->field_end(); i != e; ++i, ++idx) {
298-
if ((*i)->isZeroSize(Context) || (*i)->isUnnamedBitfield())
299+
for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
300+
i != e; ++i, ++idx) {
301+
if ((*i)->isZeroSize(Context))
299302
continue;
300-
uint64_t Offset = BaseOffset +
301-
Layout.getFieldOffset(idx) / Context.getCharWidth();
303+
304+
uint64_t Offset =
305+
BaseOffset + Layout.getFieldOffset(idx) / Context.getCharWidth();
306+
307+
// Create a single field for consecutive named bitfields using char as
308+
// base type.
309+
if ((*i)->isBitField()) {
310+
const CGBitFieldInfo &Info = CGRL.getBitFieldInfo(*i);
311+
if (Info.Offset != 0)
312+
continue;
313+
unsigned CurrentBitFieldSize = Info.StorageSize;
314+
uint64_t Size =
315+
llvm::divideCeil(CurrentBitFieldSize, Context.getCharWidth());
316+
llvm::MDNode *TBAAType = getChar();
317+
llvm::MDNode *TBAATag =
318+
getAccessTagInfo(TBAAAccessInfo(TBAAType, Size));
319+
Fields.push_back(
320+
llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag));
321+
continue;
322+
}
323+
302324
QualType FieldQTy = i->getType();
303325
if (!CollectFields(Offset, FieldQTy, Fields,
304326
MayAlias || TypeHasMayAlias(FieldQTy)))

clang/lib/CodeGen/CodeGenTBAA.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ namespace clang {
2929
class Type;
3030

3131
namespace CodeGen {
32+
class CodeGenTypes;
3233

3334
// TBAAAccessKind - A kind of TBAA memory access descriptor.
3435
enum class TBAAAccessKind : unsigned {
@@ -115,6 +116,7 @@ struct TBAAAccessInfo {
115116
/// while lowering AST types to LLVM types.
116117
class CodeGenTBAA {
117118
ASTContext &Context;
119+
CodeGenTypes &CGTypes;
118120
llvm::Module &Module;
119121
const CodeGenOptions &CodeGenOpts;
120122
const LangOptions &Features;
@@ -167,8 +169,9 @@ class CodeGenTBAA {
167169
llvm::MDNode *getBaseTypeInfoHelper(const Type *Ty);
168170

169171
public:
170-
CodeGenTBAA(ASTContext &Ctx, llvm::Module &M, const CodeGenOptions &CGO,
171-
const LangOptions &Features, MangleContext &MContext);
172+
CodeGenTBAA(ASTContext &Ctx, CodeGenTypes &CGTypes, llvm::Module &M,
173+
const CodeGenOptions &CGO, const LangOptions &Features,
174+
MangleContext &MContext);
172175
~CodeGenTBAA();
173176

174177
/// getTypeInfo - Get metadata used to describe accesses to objects of the

clang/test/CodeGen/tbaa-struct.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,11 +162,11 @@ void copy10(NamedBitfields3 *a1, NamedBitfields3 *a2) {
162162
// CHECK-OLD: [[TS3]] = !{i64 0, i64 8, !{{.*}}, i64 0, i64 2, !{{.*}}, i64 4, i64 8, !{{.*}}}
163163
// CHECK-OLD: [[TS4]] = !{i64 0, i64 1, [[TAG_CHAR]], i64 1, i64 1, [[TAG_CHAR]], i64 2, i64 1, [[TAG_CHAR]]}
164164
// CHECK-OLD: [[TS5]] = !{i64 0, i64 1, [[TAG_CHAR]], i64 4, i64 1, [[TAG_CHAR]], i64 5, i64 1, [[TAG_CHAR]]}
165-
// 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:!.+]]}
165+
// CHECK-OLD: [[TS6]] = !{i64 0, i64 2, [[TAG_CHAR]], i64 2, i64 1, [[TAG_CHAR]], i64 8, i64 8, [[TAG_DOUBLE:!.+]]}
166166
// CHECK-OLD: [[TAG_DOUBLE]] = !{[[DOUBLE:!.+]], [[DOUBLE]], i64 0}
167167
// CHECK-OLD [[DOUBLE]] = !{!"double", [[CHAR]], i64 0}
168-
// 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]]}
169-
// CHECK-OLD: [[TS8]] = !{i64 1, i64 4, [[TAG_INT]], i64 2, i64 4, [[TAG_INT]], i64 8, i64 8, [[TAG_DOUBLE]]}
168+
// 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]]}
169+
// CHECK-OLD: [[TS8]] = !{i64 0, i64 4, [[TAG_CHAR]], i64 8, i64 8, [[TAG_DOUBLE]]}
170170

171171
// CHECK-NEW-DAG: [[TYPE_char:!.*]] = !{{{.*}}, i64 1, !"omnipotent char"}
172172
// CHECK-NEW-DAG: [[TAG_char]] = !{[[TYPE_char]], [[TYPE_char]], i64 0, i64 0}

0 commit comments

Comments
 (0)