@@ -94,7 +94,7 @@ static bool TypeHasMayAlias(QualType QTy) {
9494}
9595
9696// / Check if the given type is a valid base type to be used in access tags.
97- static bool isValidBaseType (QualType QTy) {
97+ static bool isValidBaseType (QualType QTy, const CodeGenOptions &CodeGenOpts ) {
9898 if (QTy->isReferenceType ())
9999 return false ;
100100 if (const RecordType *TTy = QTy->getAs <RecordType>()) {
@@ -105,13 +105,154 @@ static bool isValidBaseType(QualType QTy) {
105105 if (RD->hasFlexibleArrayMember ())
106106 return false ;
107107 // RD can be struct, union, class, interface or enum.
108- // For now, we only handle struct and class.
109- if (RD->isStruct () || RD-> isClass ( ))
108+ if (RD-> isStruct () || RD-> isClass () ||
109+ (RD->isUnion () && CodeGenOpts. UnionTBAA ))
110110 return true ;
111111 }
112112 return false ;
113113}
114114
115+ // Appends unique tag for compatible pointee types.
116+ void CodeGenTBAA::appendPointeeName (llvm::raw_ostream &OS, const Type *Ty) {
117+ // Although type compatibilty in C standard requires cv-qualification
118+ // match and exact type match, here more relaxed rules are applied.
119+ //
120+ // For built-in types consider them 'compatible' if their respective
121+ // TBAA metadata tag is same(e.g. that makes 'int' and 'unsigned'
122+ // compatible).
123+ if (isa<BuiltinType>(Ty)) {
124+ llvm::MDNode *ScalarMD = getTypeInfoHelper (Ty);
125+ auto &Op = ScalarMD->getOperand (CodeGenOpts.NewStructPathTBAA ? 2 : 0 );
126+ assert (isa<llvm::MDString>(Op) && " Expected MDString operand" );
127+ OS << cast<llvm::MDString>(Op)->getString ().str ();
128+ }
129+
130+ // Non-builtin types are considered compatible if their tag matches.
131+ OS << Ty->getUnqualifiedDesugaredType ()
132+ ->getCanonicalTypeInternal ()
133+ .getAsString ();
134+ }
135+
136+ // / Return an LLVM TBAA metadata node appropriate for an access through
137+ // / an l-value of the given type. Type-based alias analysis takes advantage
138+ // / of the following rules from the language standards:
139+ // /
140+ // / C 6.5p7:
141+ // / An object shall have its stored value accessed only by an lvalue
142+ // / expression that has one of the following types:
143+ // / - a type compatible with the effective type of the object,
144+ // / - a qualified version of a type compatible with the effective
145+ // / type of the object,
146+ // / - a type that is the signed or unsigned type corresponding
147+ // / to the effective type of the object,
148+ // / - a type that is the signed or unsigned type corresponding
149+ // / to a qualified version of the effective type of the object,
150+ // / - an aggregate or union type that includes one of the
151+ // / aforementioned types among its members (including,
152+ // / recursively, a member of a subaggregate or contained union), or
153+ // / - a character type.
154+ // /
155+ // / C++ [basic.lval]p11:
156+ // / If a program attempts to access the stored value of an object
157+ // / through a glvalue whose type is not similar to one of the following
158+ // / types the behavior is undefined:
159+ // / - the dynamic type of the object,
160+ // / - a type that is the signed or unsigned type corresponding
161+ // / to the dynamic type of the object, or
162+ // / - a char, unsigned char, or std::byte type.
163+ // /
164+ // / The C and C++ rules about effective/dynamic type are broadly similar
165+ // / and permit memory to be reused with a different type. C does not have
166+ // / an explicit operation to change the effective type of memory; any store
167+ // / can do it. While C++ arguably does have such an operation (the standard
168+ // / global `operator new(void*, size_t)`), in practice it is important to
169+ // / be just as permissive as C. We therefore treat all stores as being able to
170+ // / change the effective type of memory, regardless of language mode. That is,
171+ // / loads have both a precondition and a postcondition on the effective
172+ // / type of the memory, but stores only have a postcondition. This imposes
173+ // / an inherent limitation that TBAA can only be used to reorder loads
174+ // / before stores. This is quite restrictive, but we don't have much of a
175+ // / choice. In practice, hoisting loads is the most important optimization
176+ // / for alias analysis to enable anyway.
177+ // /
178+ // / Therefore, given a load (and its precondition) and an earlier store
179+ // / (and its postcondition), the question posed to TBAA is whether there
180+ // / exists a type that is consistent with both accesses. If there isn't,
181+ // / it's fine to hoist the load because either the memory is non-overlapping
182+ // / or the precondition on the load is wrong (which would be UB).
183+ // /
184+ // / LLVM TBAA says that two accesses with TBAA metadata nodes may alias if:
185+ // / - the metadata nodes are the same,
186+ // / - one of the metadata nodes is a base of the other (this can be
187+ // / recursive, but it has to be the original node that's a base,
188+ // / not just that the nodes have a common base), or
189+ // / - one of the metadata nodes is a `tbaa.struct` node (the access
190+ // / necessarily being a `memcpy`) with a subobject node that would
191+ // / be allowed to alias with the other.
192+ // /
193+ // / Our job here is to produce metadata nodes that will never say that
194+ // / an alias is not allowed when there exists a type that would be consistent
195+ // / with the types of the accesses from which the nodes were produced.
196+ // /
197+ // / The last clause in both language rules permits character types to
198+ // / alias objects of any type. We handle this by converting all character
199+ // / types (as well as `std::byte` and types with the `mayalias` attribute)
200+ // / to a single metadata node (the `char` node), then making sure that
201+ // / that node is a base of every other metadata node we generate.
202+ // / We can always just conservatively use this node if we aren't otherwise
203+ // / sure how to implement the language rules for a type.
204+ // /
205+ // / Read literally, the C rule for aggregates permits an aggregate l-value
206+ // / (e.g. of type `struct { int x; }`) to be used to access an object that
207+ // / is not part of an aggregate object of that type (e.g. a local variable
208+ // / of type `int`). That case is perhaps sensical, but it would also permit
209+ // / e.g. an l-value of type `struct { int x; float f; }` to be used to
210+ // / access an object of type `float`, which is nonsense. We interpret this
211+ // / clause as just intending to permit objects to be accessed through an
212+ // / l-value that properly references a containing object.
213+ // /
214+ // / C++ does not have an explicit rule for aggregates because in C++
215+ // / a non-member access to an aggregate l-value is always a call to a
216+ // / constructor or assignment operator, which then accesses all the
217+ // / subobjects. In general, however, our interpretation of member
218+ // / accesses is that they are also an access to the containing object
219+ // / and therefore require such an object to exist at that address;
220+ // / this permits us to just use the C rule for the accesses done by
221+ // / trivial copy/move constructors/operators.
222+ // /
223+ // / Both C and C++ permit some qualification differences. In C, however,
224+ // / qualification can only differ at the outermost level, whereas C++
225+ // / allows qualification to differ in nested positions through the
226+ // / similar-types rule. This means that e.g. an l-value of type
227+ // / `const float *` is not permitted to access an object of type
228+ // / `float *` in C, but it is in C++. We use the C++ rule
229+ // / unconditionally; the C rule is needlessly strict and frequently
230+ // / violated in practice by code that we don't want to say is wrong.
231+ // / We implement this by just discarding type qualifiers within pointer-like
232+ // / types when deriving TBAA nodes; basically, we produce the TBAA node
233+ // / for the type that is unqualified at all the recursive positions
234+ // / considered by the C++ similar type rule. The implementation
235+ // / doesn't actually construct this recursively-qualified type as a
236+ // / `QualType`; it just ignores qualifiers when recursing into types.
237+ // /
238+ // / The similar-type rule only really applies to the standard CVR
239+ // / qualifiers, which never affect representations. Qualifiers such as
240+ // / address spaces that may involve a representation difference would
241+ // / be totally appropriate to distinguish for TBAA purposes. However,
242+ // / the current implementation just discards all qualifiers.
243+ // /
244+ // / We handle the signed/unsigned clause by just making unsigned types
245+ // / use the the metadata node for the signed variant of the type. In the
246+ // / language rules, this only applies at the outermost level, and e.g. an
247+ // / l-value of type `signed int *` is not permitted to alias an object of
248+ // / type `unsigned int *`. We choose not to distinguish those types when
249+ // / pointer-type TBAA is enabled, however.
250+ // /
251+ // / After discarding qualifiers and signedness differences as above,
252+ // / the language rules come down to whether the types are compatible
253+ // / (in C) or identical (in C++). Even in C, most types are compatible
254+ // / only with themselves. The exceptions will be considered in the cases
255+ // / below.
115256llvm::MDNode *CodeGenTBAA::getTypeInfoHelper (const Type *Ty) {
116257 uint64_t Size = Context.getTypeSizeInChars (Ty).getQuantity ();
117258
@@ -184,13 +325,40 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) {
184325 return getChar ();
185326
186327 // Handle pointers and references.
187- // TODO: Implement C++'s type "similarity" and consider dis-"similar"
188- // pointers distinct.
189- if (Ty->isPointerType () || Ty->isReferenceType ())
190- return createScalarTypeNode (" any pointer" , getChar (), Size);
328+ //
329+ // When PointerTBAA is disabled, all pointers and references use the same
330+ // "any pointer" TBAA node. Otherwise, we generate a type-specific TBAA
331+ // node and use the "any pointer" node as its base for compatibility between
332+ // TUs with different settings. To implement the C++ similar-type rules
333+ // (which we also adopt in C), we need to ignore qualifiers on the
334+ // pointee type, and that has to be done recursively if the pointee type
335+ // is itself a pointer-like type.
336+ //
337+ // Currently we ignore the differences between pointer-like types and just
338+ // and use this tag for the type: `p<pointer depth> <inner type tag>`.
339+ // This means we give e.g. `char **` and `char A::**` the same TBAA tag.
340+ if ((Ty->isPointerType () || Ty->isReferenceType ())) {
341+ llvm::MDNode *AnyPtr = createScalarTypeNode (" any pointer" , getChar (), Size);
342+ if (!CodeGenOpts.PointerTBAA )
343+ return AnyPtr;
344+ unsigned PtrDepth = 0 ;
345+ do {
346+ PtrDepth++;
347+ Ty = Ty->getPointeeType ().getTypePtr ()->getUnqualifiedDesugaredType ();
348+ // Any array-like type is considered a pointer-to qualification.
349+ if (Ty && Ty->isArrayType ()) {
350+ Ty = Ty->getAsArrayTypeUnsafe ()->getElementType ().getTypePtr ();
351+ }
352+ } while (!Ty->getPointeeType ().isNull ());
353+ std::string PtrName;
354+ llvm::raw_string_ostream OS{PtrName};
355+ OS << " p" << PtrDepth << " " ;
356+ appendPointeeName (OS, Ty);
357+ return createScalarTypeNode (PtrName, AnyPtr, Size);
358+ }
191359
192360 // Accesses to arrays are accesses to objects of their element types.
193- if (CodeGenOpts.NewStructPathTBAA && Ty->isArrayType ())
361+ if (CodeGenOpts.ArrayTBAA && Ty->isArrayType ())
194362 return getTypeInfo (cast<ArrayType>(Ty)->getElementType ());
195363
196364 // Enum types are distinct types. In C++ they have "underlying types",
@@ -241,7 +409,7 @@ llvm::MDNode *CodeGenTBAA::getTypeInfo(QualType QTy) {
241409 // subsequent accesses to direct and indirect members of that aggregate will
242410 // be considered may-alias too.
243411 // TODO: Combine getTypeInfo() and getBaseTypeInfo() into a single function.
244- if (isValidBaseType (QTy))
412+ if (isValidBaseType (QTy, CodeGenOpts ))
245413 return getBaseTypeInfo (QTy);
246414
247415 const Type *Ty = Context.getCanonicalType (QTy).getTypePtr ();
@@ -353,7 +521,7 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type *Ty) {
353521 const CXXRecordDecl *BaseRD = BaseQTy->getAsCXXRecordDecl ();
354522 if (BaseRD->isEmpty ())
355523 continue ;
356- llvm::MDNode *TypeNode = isValidBaseType (BaseQTy)
524+ llvm::MDNode *TypeNode = isValidBaseType (BaseQTy, CodeGenOpts )
357525 ? getBaseTypeInfo (BaseQTy)
358526 : getTypeInfo (BaseQTy);
359527 if (!TypeNode)
@@ -378,8 +546,9 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type *Ty) {
378546 if (Field->isZeroSize (Context) || Field->isUnnamedBitfield ())
379547 continue ;
380548 QualType FieldQTy = Field->getType ();
381- llvm::MDNode *TypeNode = isValidBaseType (FieldQTy) ?
382- getBaseTypeInfo (FieldQTy) : getTypeInfo (FieldQTy);
549+ llvm::MDNode *TypeNode = isValidBaseType (FieldQTy, CodeGenOpts)
550+ ? getBaseTypeInfo (FieldQTy)
551+ : getTypeInfo (FieldQTy);
383552 if (!TypeNode)
384553 return nullptr ;
385554
@@ -417,7 +586,7 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type *Ty) {
417586}
418587
419588llvm::MDNode *CodeGenTBAA::getBaseTypeInfo (QualType QTy) {
420- if (!isValidBaseType (QTy))
589+ if (!isValidBaseType (QTy, CodeGenOpts ))
421590 return nullptr ;
422591
423592 const Type *Ty = Context.getCanonicalType (QTy).getTypePtr ();
0 commit comments