aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Analysis/ThreadSafetyCommon.cpp
diff options
context:
space:
mode:
authorMarco Elver <elver@google.com>2025-09-23 09:57:35 +0200
committerGitHub <noreply@github.com>2025-09-23 09:57:35 +0200
commit08de00ad22e71d74bcfdecd61502d0caea7eefb0 (patch)
treebd5a20ecda5e8a4b56bda77edd41688c59250ba0 /clang/lib/Analysis/ThreadSafetyCommon.cpp
parent242a1e2fb1b2ddefc8dcde73e22ce3f06f6a8188 (diff)
downloadllvm-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.cpp12
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()) {