diff options
author | Florian Hahn <flo@fhahn.com> | 2024-07-12 20:56:10 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-12 20:56:10 +0100 |
commit | 038c48c1f41119d667fa55e17e040281378071f3 (patch) | |
tree | 202cea16a9993b58acab61c77347950eb3b2c6f8 /clang/lib/CodeGen/CodeGenTBAA.cpp | |
parent | 5b82741a011c1b080ab03dbf70b808bab3813ea9 (diff) | |
download | llvm-038c48c1f41119d667fa55e17e040281378071f3.zip llvm-038c48c1f41119d667fa55e17e040281378071f3.tar.gz llvm-038c48c1f41119d667fa55e17e040281378071f3.tar.bz2 |
[TBAA] Emit distinct TBAA tags for pointers with different depths,types. (#76612)
This patch extends Clang's TBAA generation code to emit distinct tags
for incompatible pointer types.
Pointers with different element types are incompatible if the pointee
types are also incompatible (modulo sugar/modifiers).
Express this in TBAA by generating different tags for pointers based on
the pointer depth and pointee type. To get the TBAA tag for the pointee
type it uses getTypeInfoHelper on the pointee type.
(Moved from https://reviews.llvm.org/D122573)
PR: https://github.com/llvm/llvm-project/pull/76612
Diffstat (limited to 'clang/lib/CodeGen/CodeGenTBAA.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenTBAA.cpp | 54 |
1 files changed, 50 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp index 284421f..6791008 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.cpp +++ b/clang/lib/CodeGen/CodeGenTBAA.cpp @@ -185,10 +185,56 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) { return getChar(); // Handle pointers and references. - // TODO: Implement C++'s type "similarity" and consider dis-"similar" - // pointers distinct. - if (Ty->isPointerType() || Ty->isReferenceType()) - return createScalarTypeNode("any pointer", getChar(), Size); + // + // C has a very strict rule for pointer aliasing. C23 6.7.6.1p2: + // For two pointer types to be compatible, both shall be identically + // qualified and both shall be pointers to compatible types. + // + // This rule is impractically strict; we want to at least ignore CVR + // qualifiers. Distinguishing by CVR qualifiers would make it UB to + // e.g. cast a `char **` to `const char * const *` and dereference it, + // which is too common and useful to invalidate. C++'s similar types + // rule permits qualifier differences in these nested positions; in fact, + // C++ even allows that cast as an implicit conversion. + // + // Other qualifiers could theoretically be distinguished, especially if + // they involve a significant representation difference. We don't + // currently do so, however. + // + // Computing the pointee type string recursively is implicitly more + // forgiving than the standards require. Effectively, we are turning + // the question "are these types compatible/similar" into "are + // accesses to these types allowed to alias". In both C and C++, + // the latter question has special carve-outs for signedness + // mismatches that only apply at the top level. As a result, we are + // allowing e.g. `int *` l-values to access `unsigned *` objects. + if (Ty->isPointerType() || Ty->isReferenceType()) { + llvm::MDNode *AnyPtr = createScalarTypeNode("any pointer", getChar(), Size); + if (!CodeGenOpts.PointerTBAA) + return AnyPtr; + // Compute the depth of the pointer and generate a tag of the form "p<depth> + // <base type tag>". + unsigned PtrDepth = 0; + do { + PtrDepth++; + Ty = Ty->getPointeeType().getTypePtr(); + } while (Ty->isPointerType()); + // TODO: Implement C++'s type "similarity" and consider dis-"similar" + // pointers distinct for non-builtin types. + if (isa<BuiltinType>(Ty)) { + llvm::MDNode *ScalarMD = getTypeInfoHelper(Ty); + StringRef Name = + cast<llvm::MDString>( + ScalarMD->getOperand(CodeGenOpts.NewStructPathTBAA ? 2 : 0)) + ->getString(); + SmallString<256> OutName("p"); + OutName += std::to_string(PtrDepth); + OutName += " "; + OutName += Name; + return createScalarTypeNode(OutName, AnyPtr, Size); + } + return AnyPtr; + } // Accesses to arrays are accesses to objects of their element types. if (CodeGenOpts.NewStructPathTBAA && Ty->isArrayType()) |