[clang] 346da8d - [analyzer] Default to fresh state in addTransitionImpl (#234123)

via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 21 04:15:23 PDT 2026


Author: DonĂ¡t Nagy
Date: 2026-10-21T13:15:17+02:00
New Revision: 346da8d3b09803d4f7bef200c1a46aca3a935252

URL: https://github.com/llvm/llvm-project/commit/346da8d3b09803d4f7bef200c1a46aca3a935252
DIFF: https://github.com/llvm/llvm-project/commit/346da8d3b09803d4f7bef200c1a46aca3a935252.diff

LOG: [analyzer] Default to fresh state in addTransitionImpl (#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.

Added: 
    

Modified: 
    clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
index 11d89aa75760d..1e212d0de3622 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