clang: lib/CodeGen/CodeGenTBAA.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
28#include "llvm/IR/LLVMContext.h"
29#include "llvm/IR/Metadata.h"
30#include "llvm/IR/Module.h"
31#include "llvm/IR/Type.h"
32#include "llvm/Support/Debug.h"
33using namespace clang;
34using namespace CodeGen;
35
39 : Context(Ctx), CGTypes(CGTypes), Module(M), CodeGenOpts(CGO),
40 Features(Features),
42 MDHelper(M.getContext()), Root(nullptr), Char(nullptr) {}
43
45}
46
47llvm::MDNode *CodeGenTBAA::getRoot() {
48
49
50
51
52 if (!Root) {
53 if (Features.CPlusPlus)
54 Root = MDHelper.createTBAARoot("Simple C++ TBAA");
55 else
56 Root = MDHelper.createTBAARoot("Simple C/C++ TBAA");
57 }
58
59 return Root;
60}
61
62llvm::MDNode *CodeGenTBAA::createScalarTypeNode(StringRef Name,
64 uint64_t Size) {
65 if (CodeGenOpts.NewStructPathTBAA) {
66 llvm::Metadata *Id = MDHelper.createString(Name);
67 return MDHelper.createTBAATypeNode(Parent, Size, Id);
68 }
69 return MDHelper.createTBAAScalarTypeNode(Name, Parent);
70}
71
72llvm::MDNode *CodeGenTBAA::getChar() {
73
74
75
76
77 if (!Char)
78 Char = createScalarTypeNode("omnipotent char", getRoot(), 1);
79
80 return Char;
81}
82
84
86 if (TD->hasAttr())
87 return true;
88
89
90
91
93 if (TT->getDecl()->hasAttr())
94 return true;
95 QTy = TT->desugar();
96 }
97 return false;
98}
99
100
104
105 if (!RD)
106 return false;
108 return false;
109
110
112 return true;
113 }
114 return false;
115}
116
117llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) {
119
120
121 if (const BuiltinType *BTy = dyn_cast(Ty)) {
122 switch (BTy->getKind()) {
123
124
125
126
127
128 case BuiltinType::Char_U:
129 case BuiltinType::Char_S:
130 case BuiltinType::UChar:
131 case BuiltinType::SChar:
132 return getChar();
133
134
135 case BuiltinType::UShort:
137 case BuiltinType::UInt:
139 case BuiltinType::ULong:
141 case BuiltinType::ULongLong:
143 case BuiltinType::UInt128:
145
146 case BuiltinType::UShortFract:
148 case BuiltinType::UFract:
150 case BuiltinType::ULongFract:
152
153 case BuiltinType::SatUShortFract:
155 case BuiltinType::SatUFract:
157 case BuiltinType::SatULongFract:
159
160 case BuiltinType::UShortAccum:
162 case BuiltinType::UAccum:
164 case BuiltinType::ULongAccum:
166
167 case BuiltinType::SatUShortAccum:
169 case BuiltinType::SatUAccum:
171 case BuiltinType::SatULongAccum:
173
174
175
176
177 default:
178 return createScalarTypeNode(BTy->getName(Features), getChar(), Size);
179 }
180 }
181
182
183
184
186 return getChar();
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
205 llvm::MDNode *AnyPtr = createScalarTypeNode("any pointer", getChar(), Size);
206 if (!CodeGenOpts.PointerTBAA)
207 return AnyPtr;
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224 unsigned PtrDepth = 0;
225 do {
226 PtrDepth++;
229 assert(!isa(Ty));
230
231
232
233
234
235
236
238 if (isa(Ty)) {
239 llvm::MDNode *ScalarMD = getTypeInfoHelper(Ty);
240 StringRef Name =
241 castllvm::MDString(
242 ScalarMD->getOperand(CodeGenOpts.NewStructPathTBAA ? 2 : 0))
243 ->getString();
244 TyName = Name;
245 } else {
246
247
248
250 if (!RT)
251 return AnyPtr;
252
253
254
255
256
257
258
259
260
261
262
263
264 if (!RT->getDecl()->getDeclName())
265 return AnyPtr;
266
267
268 llvm::raw_svector_ostream TyOut(TyName);
269 MangleCtx->mangleCanonicalTypeName(QualType(Ty, 0), TyOut);
270 }
271
273 OutName += std::to_string(PtrDepth);
274 OutName += " ";
275 OutName += TyName;
276 return createScalarTypeNode(OutName, AnyPtr, Size);
277 }
278
279
280 if (CodeGenOpts.NewStructPathTBAA && Ty->isArrayType())
281 return getTypeInfo(cast(Ty)->getElementType());
282
283
284
285 if (const EnumType *ETy = dyn_cast(Ty)) {
286 if (!Features.CPlusPlus)
287 return getTypeInfo(ETy->getDecl()->getIntegerType());
288
289
290
291
292
293 if (!ETy->getDecl()->isExternallyVisible())
294 return getChar();
295
297 llvm::raw_svector_ostream Out(OutName);
300 return createScalarTypeNode(OutName, getChar(), Size);
301 }
302
303 if (const auto *EIT = dyn_cast(Ty)) {
305 llvm::raw_svector_ostream Out(OutName);
306
307
308 Out << "_BitInt(" << EIT->getNumBits() << ')';
309 return createScalarTypeNode(OutName, getChar(), Size);
310 }
311
312
313 return getChar();
314}
315
317
318
319 if (!Features.Sanitize.has(SanitizerKind::Type) &&
320 (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing))
321 return nullptr;
322
323
324
326 return getChar();
327
328
329
330
331
332
333
334
336 return getValidBaseTypeInfo(QTy);
337
339 if (llvm::MDNode *N = MetadataCache[Ty])
340 return N;
341
342
343
344
345 llvm::MDNode *TypeNode = getTypeInfoHelper(Ty);
346 return MetadataCache[Ty] = TypeNode;
347}
348
350
351
354
357
360}
361
363 const llvm::DataLayout &DL = Module.getDataLayout();
364 unsigned Size = DL.getPointerTypeSize(VTablePtrType);
365 return TBAAAccessInfo(createScalarTypeNode("vtable pointer", getRoot(), Size),
366 Size);
367}
368
369bool
370CodeGenTBAA::CollectFields(uint64_t BaseOffset,
373 Fields,
375
376
378 if (TTy->isUnionType()) {
380 llvm::MDNode *TBAAType = getChar();
382 Fields.push_back(
383 llvm::MDBuilder::TBAAStructField(BaseOffset, Size, TBAATag));
384 return true;
385 }
388 return false;
389
390
392 if (Decl->bases_begin() != Decl->bases_end())
393 return false;
394
397
398 unsigned idx = 0;
400 i != e; ++i, ++idx) {
402 continue;
403
404 uint64_t Offset =
406
407
408
409 if ((*i)->isBitField()) {
411
412
413
417 if (!IsFirst)
418 continue;
419 unsigned CurrentBitFieldSize = Info.StorageSize;
420 uint64_t Size =
421 llvm::divideCeil(CurrentBitFieldSize, Context.getCharWidth());
422 llvm::MDNode *TBAAType = getChar();
423 llvm::MDNode *TBAATag =
425 Fields.push_back(
426 llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag));
427 continue;
428 }
429
430 QualType FieldQTy = i->getType();
431 if (!CollectFields(Offset, FieldQTy, Fields,
433 return false;
434 }
435 return true;
436 }
437
438
439 uint64_t Offset = BaseOffset;
443 Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag));
444 return true;
445}
446
447llvm::MDNode *
449 if (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing)
450 return nullptr;
451
453
454 if (llvm::MDNode *N = StructMetadataCache[Ty])
455 return N;
456
459 return MDHelper.createTBAAStructNode(Fields);
460
461
462 return StructMetadataCache[Ty] = nullptr;
463}
464
465llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type *Ty) {
466 if (auto *TTy = dyn_cast(Ty)) {
469 using TBAAStructField = llvm::MDBuilder::TBAAStructField;
471 if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) {
472
473
474
475 if (CodeGenOpts.NewStructPathTBAA && CXXRD->getNumVBases() != 0)
476 return nullptr;
478 if (B.isVirtual())
479 continue;
480 QualType BaseQTy = B.getType();
483 continue;
485 ? getValidBaseTypeInfo(BaseQTy)
487 if (!TypeNode)
488 return nullptr;
490 uint64_t Size =
492 Fields.push_back(
493 llvm::MDBuilder::TBAAStructField(Offset, Size, TypeNode));
494 }
495
496
497
498
499
500 llvm::sort(Fields,
501 [](const TBAAStructField &A, const TBAAStructField &B) {
502 return A.Offset < B.Offset;
503 });
504 }
506 if (Field->isZeroSize(Context) || Field->isUnnamedBitField())
507 continue;
510 ? getValidBaseTypeInfo(FieldQTy)
512 if (!TypeNode)
513 return nullptr;
514
518 Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size,
519 TypeNode));
520 }
521
523 if (Features.CPlusPlus) {
524
525 llvm::raw_svector_ostream Out(OutName);
528 } else {
530 }
531
532 if (CodeGenOpts.NewStructPathTBAA) {
533 llvm::MDNode *Parent = getChar();
535 llvm::Metadata *Id = MDHelper.createString(OutName);
536 return MDHelper.createTBAATypeNode(Parent, Size, Id, Fields);
537 }
538
539
541 for (const auto &Field : Fields)
542 OffsetsAndTypes.push_back(std::make_pair(Field.Type, Field.Offset));
543 return MDHelper.createTBAAStructTypeNode(OutName, OffsetsAndTypes);
544 }
545
546 return nullptr;
547}
548
549llvm::MDNode *CodeGenTBAA::getValidBaseTypeInfo(QualType QTy) {
550 assert(isValidBaseType(QTy) && "Must be a valid base type");
551
553
554
555 auto I = BaseTypeMetadataCache.find(Ty);
556 if (I != BaseTypeMetadataCache.end())
557 return I->second;
558
559
560
561 llvm::MDNode *TypeNode = getBaseTypeInfoHelper(Ty);
562 LLVM_ATTRIBUTE_UNUSED auto inserted =
563 BaseTypeMetadataCache.insert({Ty, TypeNode});
564 assert(inserted.second && "BaseType metadata was already inserted");
565
566 return TypeNode;
567}
568
570 return isValidBaseType(QTy) ? getValidBaseTypeInfo(QTy) : nullptr;
571}
572
574 assert(!Info.isIncomplete() && "Access to an object of an incomplete type!");
575
578
580 return nullptr;
581
582 if (!CodeGenOpts.StructPathTBAA)
584
585 llvm::MDNode *&N = AccessTagMetadataCache[Info];
586 if (N)
587 return N;
588
591 assert(!Info.Offset && "Nonzero offset for an access with no base type!");
592 }
593 if (CodeGenOpts.NewStructPathTBAA) {
594 return N = MDHelper.createTBAAAccessTag(Info.BaseType, Info.AccessType,
596 }
597 return N = MDHelper.createTBAAStructTagNode(Info.BaseType, Info.AccessType,
599}
600
606}
607
611 if (InfoA == InfoB)
612 return InfoA;
613
614 if (!InfoA || !InfoB)
616
619
620
621
622
624}
625
629 if (DestInfo == SrcInfo)
630 return DestInfo;
631
632 if (!DestInfo || !SrcInfo)
634
637
638
639
640
642}
Defines the clang::ASTContext interface.
static bool TypeHasMayAlias(QualType QTy)
static bool isValidBaseType(QualType QTy)
Check if the given type is a valid base type to be used in access tags.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
CanQualType SatLongAccumTy
CanQualType SatShortFractTy
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
CanQualType SatLongFractTy
const TargetInfo & getTargetInfo() const
CanQualType SatShortAccumTy
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getDataSize() const
getDataSize() - Get the record data size, which is the record size without tail padding,...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
This class is used for builtin types like 'int'.
Represents a base class of a C++ class.
Represents a C++ struct/union/class.
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
MangleContext & getMangleContext()
Gets the mangle context.
CGRecordLayout - This class handles struct and union layout info while lowering AST types to LLVM typ...
const CGBitFieldInfo & getBitFieldInfo(const FieldDecl *FD) const
Return the BitFieldInfo that corresponds to the field FD.
llvm::MDNode * getBaseTypeInfo(QualType QTy)
getBaseTypeInfo - Get metadata that describes the given base access type.
llvm::MDNode * getTypeInfo(QualType QTy)
getTypeInfo - Get metadata used to describe accesses to objects of the given type.
TBAAAccessInfo getVTablePtrAccessInfo(llvm::Type *VTablePtrType)
getVTablePtrAccessInfo - Get the TBAA information that describes an access to a virtual table pointer...
TBAAAccessInfo mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo DestInfo, TBAAAccessInfo SrcInfo)
mergeTBAAInfoForMemoryTransfer - Get merged TBAA information for the purpose of memory transfer calls...
TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, TBAAAccessInfo TargetInfo)
mergeTBAAInfoForCast - Get merged TBAA information for the purpose of type casts.
TBAAAccessInfo mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA, TBAAAccessInfo InfoB)
mergeTBAAInfoForConditionalOperator - Get merged TBAA information for the purpose of conditional oper...
llvm::MDNode * getAccessTagInfo(TBAAAccessInfo Info)
getAccessTagInfo - Get TBAA tag for a given memory access.
llvm::MDNode * getTBAAStructInfo(QualType QTy)
getTBAAStructInfo - Get the TBAAStruct MDNode to be used for a memcpy of the given type.
CodeGenTBAA(ASTContext &Ctx, CodeGenTypes &CGTypes, llvm::Module &M, const CodeGenOptions &CGO, const LangOptions &Features)
TBAAAccessInfo getAccessInfo(QualType AccessType)
getAccessInfo - Get TBAA information that describes an access to an object of the given type.
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
CGCXXABI & getCXXABI() const
const CGRecordLayout & getCGRecordLayout(const RecordDecl *)
getCGRecordLayout - Return record layout info for the given record decl.
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
Decl - This represents one declaration (or definition), e.g.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
Represents a member of a struct/union/class.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
SanitizerSet Sanitize
Set of enabled sanitizers.
virtual void mangleCanonicalTypeName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0
Generates a unique string for an externally visible type for use with TBAA or type uniquing.
Describes a module or submodule.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
A (possibly-)qualified type.
Represents a struct/union/class.
bool hasFlexibleArrayMember() const
field_iterator field_end() const
field_range fields() const
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
field_iterator field_begin() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Exposes information about the current target.
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isPointerType() const
bool isReferenceType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
bool isStdByteType() const
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
const T * getAs() const
Member-template getAs'.
TagDecl * getAsTagDecl() const
Retrieves the TagDecl that this type refers to, either because the type is a TagType or because it is...
Defines the clang::TargetInfo interface.
bool isEmptyFieldForLayout(const ASTContext &Context, const FieldDecl *FD)
isEmptyFieldForLayout - Return true iff the field is "empty", that is, either a zero-width bit-field ...
The JSON file list parser is used to communicate input to InstallAPI.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
Structure with information about how a bitfield should be accessed.
unsigned Offset
The offset within a contiguous run of bitfields that are represented as a single "field" within the L...
unsigned Size
The total size of the bit-field, in bits.
unsigned StorageSize
The storage size in bits which should be used when accessing this bitfield.
llvm::MDNode * AccessType
AccessType - The final access type.
uint64_t Offset
Offset - The byte offset of the final access within the base one.
static TBAAAccessInfo getMayAliasInfo()
uint64_t Size
Size - The size of access, in bytes.
static TBAAAccessInfo getIncompleteInfo()
llvm::MDNode * BaseType
BaseType - The base/leading access type.
bool isIncomplete() const
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.