@@ -185,6 +185,29 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) {
185185 return getChar ();
186186
187187 // Handle pointers and references.
188+ //
189+ // C has a very strict rule for pointer aliasing. C23 6.7.6.1p2:
190+ // For two pointer types to be compatible, both shall be identically
191+ // qualified and both shall be pointers to compatible types.
192+ //
193+ // This rule is impractically strict; we want to at least ignore CVR
194+ // qualifiers. Distinguishing by CVR qualifiers would make it UB to
195+ // e.g. cast a `char **` to `const char * const *` and dereference it,
196+ // which is too common and useful to invalidate. C++'s similar types
197+ // rule permits qualifier differences in these nested positions; in fact,
198+ // C++ even allows that cast as an implicit conversion.
199+ //
200+ // Other qualifiers could theoretically be distinguished, especially if
201+ // they involve a significant representation difference. We don't
202+ // currently do so, however.
203+ //
204+ // Computing the pointee type string recursively is implicitly more
205+ // forgiving than the standards require. Effectively, we are turning
206+ // the question "are these types compatible/similar" into "are
207+ // accesses to these types allowed to alias". In both C and C++,
208+ // the latter question has special carve-outs for signedness
209+ // mismatches that only apply at the top level. As a result, we are
210+ // allowing e.g. `int *` l-values to access `unsigned *` objects.
188211 if (Ty->isPointerType () || Ty->isReferenceType ()) {
189212 llvm::MDNode *AnyPtr = createScalarTypeNode (" any pointer" , getChar (), Size);
190213 if (CodeGenOpts.RelaxedPointerAliasing )
@@ -195,7 +218,7 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) {
195218 do {
196219 PtrDepth++;
197220 Ty = Ty->getPointeeType ().getTypePtr ();
198- } while (Ty->isPointerType () || Ty-> isReferenceType () );
221+ } while (Ty->isPointerType ());
199222 // TODO: Implement C++'s type "similarity" and consider dis-"similar"
200223 // pointers distinct for non-builtin types.
201224 if (isa<BuiltinType>(Ty)) {
0 commit comments