diff options
author | Marco Elver <elver@google.com> | 2025-09-23 09:57:35 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-09-23 09:57:35 +0200 |
commit | 08de00ad22e71d74bcfdecd61502d0caea7eefb0 (patch) | |
tree | bd5a20ecda5e8a4b56bda77edd41688c59250ba0 /clang/lib/Analysis/ThreadSafetyCommon.cpp | |
parent | 242a1e2fb1b2ddefc8dcde73e22ce3f06f6a8188 (diff) | |
download | llvm-08de00ad22e71d74bcfdecd61502d0caea7eefb0.zip llvm-08de00ad22e71d74bcfdecd61502d0caea7eefb0.tar.gz llvm-08de00ad22e71d74bcfdecd61502d0caea7eefb0.tar.bz2 |
Thread Safety Analysis: Fix recursive capability alias resolution (#159921)
Fix a false positive in thread safety alias analysis caused by incorrect
late resolution of aliases. The analysis previously failed to
distinguish between an alias and its defining expression; reassigning a
variable within that expression (e.g., `ptr` in `alias = ptr->field`)
would incorrectly change the dependent alias as well.
The fix is to properly use LocalVariableMap::lookupExpr's updated
context in a recursive lookup.
Reported-by: Christoph Hellwig <hch@lst.de>
Link: https://lkml.kernel.org/r/20250919140803.GA23745@lst.de
Diffstat (limited to 'clang/lib/Analysis/ThreadSafetyCommon.cpp')
-rw-r--r-- | clang/lib/Analysis/ThreadSafetyCommon.cpp | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/clang/lib/Analysis/ThreadSafetyCommon.cpp b/clang/lib/Analysis/ThreadSafetyCommon.cpp index 25ad673..ef48ae4 100644 --- a/clang/lib/Analysis/ThreadSafetyCommon.cpp +++ b/clang/lib/Analysis/ThreadSafetyCommon.cpp @@ -248,9 +248,17 @@ til::SExpr *SExprBuilder::translateVariable(const VarDecl *VD, // defining VD, use its pre-assignment value to break the cycle. if (VarsBeingTranslated.contains(VD->getCanonicalDecl())) return new (Arena) til::LiteralPtr(VD); - VarsBeingTranslated.insert(VD->getCanonicalDecl()); + + // The closure captures state that is updated to correctly translate chains of + // aliases. Restore it when we are done with recursive translation. auto Cleanup = llvm::make_scope_exit( - [&] { VarsBeingTranslated.erase(VD->getCanonicalDecl()); }); + [&, RestoreClosure = + VarsBeingTranslated.empty() ? LookupLocalVarExpr : nullptr] { + VarsBeingTranslated.erase(VD->getCanonicalDecl()); + if (VarsBeingTranslated.empty()) + LookupLocalVarExpr = RestoreClosure; + }); + VarsBeingTranslated.insert(VD->getCanonicalDecl()); QualType Ty = VD->getType(); if (!VD->isStaticLocal() && Ty->isPointerType()) { |