[clang] [analyzer] Default to fresh state in addTransitionImpl (PR #234123)
DonĂ¡t Nagy via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 21 02:13:33 PDT 2026
https://github.com/NagyDonat created https://github.com/llvm/llvm-project/pull/234123
When `CheckerContext::addTransitionImpl` is called with a null `State`, it defaulted to using the state of the node that was passed to the constructor of `CheckerContext` -- even if the parent of the new node (`P`) was another more recent node.
This logic could have "jumped back" to a slightly older, obsolete state in the case when the state of `P` was distinct from the state of the node that was passed to the constructor of `CheckerContext`. I did not observe this in practice (and I verified that it never happens among the LIT tests), but it is better to completely rule it out.
Using the state of `P` should be a very safe fallback choice, so I don't expect disruptions from this change. A checker has to be _very_ buggy if this change (i.e. _not_ forgetting its state updates) triggered buggy behavior in it.
>From 813f6d9c461164d0fc0d69f925dbbb15426a7284 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <donat.nagy at ericsson.com>
Date: Wed, 21 Oct 2026 10:45:19 +0200
Subject: [PATCH] [analyzer] Default to fresh state in addTransitionImpl
When `CheckerContext::addTransitionImpl` is called with a null `State`,
it defaulted to using the state of the node that was passed to the
constructor of `CheckerContext` -- even if the parent of the new node
(`P`) was another more recent node.
This logic could have "jumped back" to a slightly older, obsolete state
in the case when the state of `P` was distinct from the state of the
node that was passed to the constructor of `CheckerContext`. I did not
observe this in practice (and I verified that it never happens among the
LIT tests), but it is better to completely rule it out.
Using the state of `P` should be a very safe fallback choice, I don't
expect disruptions from this change. A checker has to be _very_ buggy if
this change (i.e. _not_ discarding its state changes) triggered buggy
behavior in it.
---
.../StaticAnalyzer/Core/PathSensitive/CheckerContext.h | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
index 11d89aa75760d1..1e212d0de36225 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
@@ -478,12 +478,8 @@ class CheckerContext {
if (!P)
P = getPredecessor();
- // TODO: Defaulting to `getState()` (the state of `getPredecessor()`, i.e.
- // the node passed to the constructor of `CheckerContext`) only makes sense
- // in the common case when `P == getPredecessor()` -- otherwise this could
- // "jump back" to an obsolete, older state.
if (!State)
- State = getState();
+ State = P->getState();
Frontier.erase(P);
ExplodedNode *N =
More information about the cfe-commits
mailing list