https://github.com/NagyDonat updated 
https://github.com/llvm/llvm-project/pull/205151

From f4916c3f3bb60e776e30dbea2f0b81af064f6b51 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]>
Date: Mon, 22 Jun 2026 16:57:43 +0200
Subject: [PATCH 01/12] Modernize an old-style loop

---
 clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index f2682b25630e1..7e2ff8146dbe3 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -51,11 +51,9 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* B,
   getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, B, *this);
 
   // With both the LHS and RHS evaluated, process the operation itself.
-  for (ExplodedNodeSet::iterator it=CheckedSet.begin(), ei=CheckedSet.end();
-         it != ei; ++it) {
-
-    ProgramStateRef state = (*it)->getState();
-    const StackFrame *SF = (*it)->getStackFrame();
+  for (ExplodedNode *N : CheckedSet) {
+    ProgramStateRef state = N->getState();
+    const StackFrame *SF = N->getStackFrame();
     SVal LeftV = state->getSVal(LHS, SF);
     SVal RightV = state->getSVal(RHS, SF);
 
@@ -72,13 +70,13 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* 
B,
       // Simulate the effects of a "store":  bind the value of the RHS
       // to the L-Value represented by the LHS.
       SVal ExprVal = B->isGLValue() ? LeftV : RightV;
-      evalStore(Tmp2, B, LHS, *it, state->BindExpr(B, SF, ExprVal), LeftV,
+      evalStore(Tmp2, B, LHS, N, state->BindExpr(B, SF, ExprVal), LeftV,
                 RightV);
       continue;
     }
 
     if (!B->isAssignmentOp()) {
-      NodeBuilder Bldr(*it, Tmp2, *currBldrCtx);
+      NodeBuilder Bldr(N, Tmp2, *currBldrCtx);
 
       if (B->isAdditiveOp()) {
         // TODO: This can be removed after we enable history tracking with
@@ -109,7 +107,7 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* 
B,
         state = escapeValues(state, RightV, PSK_EscapeOther);
       }
 
-      Bldr.generateNode(B, *it, state);
+      Bldr.generateNode(B, N, state);
       continue;
     }
 
@@ -134,7 +132,7 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* 
B,
     // null dereferences, and so on.
     ExplodedNodeSet Tmp;
     SVal location = LeftV;
-    evalLoad(Tmp, B, LHS, *it, state, location);
+    evalLoad(Tmp, B, LHS, N, state, location);
 
     for (ExplodedNode *N : Tmp) {
       state = N->getState();

From 21862d54e5cd0c611370e8ef43f1d45940d47ea1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]>
Date: Mon, 22 Jun 2026 17:47:34 +0200
Subject: [PATCH 02/12] Conjured symbols are 15 year old, no longer
 EXPERIMENTAL

---
 clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp | 2 --
 1 file changed, 2 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 7e2ff8146dbe3..3dfeb1ad15002 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -60,7 +60,6 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* B,
     BinaryOperator::Opcode Op = B->getOpcode();
 
     if (Op == BO_Assign) {
-      // EXPERIMENTAL: "Conjured" symbols.
       // FIXME: Handle structs.
       if (RightV.isUnknown()) {
         unsigned Count = getNumVisitedCurrent();
@@ -157,7 +156,6 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* 
B,
       SVal Result = svalBuilder.evalCast(evalBinOp(state, Op, V, RightV, CTy),
                                          B->getType(), CTy);
 
-      // EXPERIMENTAL: "Conjured" symbols.
       // FIXME: Handle structs.
 
       SVal LHSVal;

From 0cc42c42c1222bd57f846bbe9ee523a142e49452 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]>
Date: Mon, 22 Jun 2026 17:54:09 +0200
Subject: [PATCH 03/12] Remove obsolete FIXMEs from 2011

Assignment operartors do "Handle structs" nowdays, and builtin compound
assignment operators (like `+=`) don't need to handle structs.
---
 clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 3dfeb1ad15002..312c1941d1616 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -60,7 +60,6 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* B,
     BinaryOperator::Opcode Op = B->getOpcode();
 
     if (Op == BO_Assign) {
-      // FIXME: Handle structs.
       if (RightV.isUnknown()) {
         unsigned Count = getNumVisitedCurrent();
         RightV = svalBuilder.conjureSymbolVal(nullptr, getCFGElementRef(), SF,
@@ -156,8 +155,6 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* 
B,
       SVal Result = svalBuilder.evalCast(evalBinOp(state, Op, V, RightV, CTy),
                                          B->getType(), CTy);
 
-      // FIXME: Handle structs.
-
       SVal LHSVal;
 
       if (Result.isUnknown()) {

From 680dee983e13ebc3ac750835b10e5e11a435ebd0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]>
Date: Mon, 22 Jun 2026 18:04:20 +0200
Subject: [PATCH 04/12] Remove obsolete TODO from 2012

This code block handles `pointer + integer`, `pointer - integer` or
`integer + pointer` expressions, which produce values that are
represeted by element regions (wrapped in `loc::MemRegionVal`).

Perhaps some old plans hoped to use `SymSymExpr` (or perhaps
`SymIntExpr`) in these situations, but they are irrelevant now.
---
 clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp | 2 --
 1 file changed, 2 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 312c1941d1616..dc2bc9e681bcd 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -77,8 +77,6 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* B,
       NodeBuilder Bldr(N, Tmp2, *currBldrCtx);
 
       if (B->isAdditiveOp()) {
-        // TODO: This can be removed after we enable history tracking with
-        // SymSymExpr.
         unsigned Count = getNumVisitedCurrent();
         RightV = conjureOffsetSymbolOnLocation(
             RightV, LeftV, getCFGElementRef(), RHS->getType(), svalBuilder,

From b7606aefc3fb4a16084ef17693592b49bfab3da6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]>
Date: Mon, 22 Jun 2026 18:29:38 +0200
Subject: [PATCH 05/12] Capitalize local 'state'

---
 clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp | 34 +++++++++----------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index dc2bc9e681bcd..4e14062d27c39 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -52,10 +52,10 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* 
B,
 
   // With both the LHS and RHS evaluated, process the operation itself.
   for (ExplodedNode *N : CheckedSet) {
-    ProgramStateRef state = N->getState();
+    ProgramStateRef State = N->getState();
     const StackFrame *SF = N->getStackFrame();
-    SVal LeftV = state->getSVal(LHS, SF);
-    SVal RightV = state->getSVal(RHS, SF);
+    SVal LeftV = State->getSVal(LHS, SF);
+    SVal RightV = State->getSVal(RHS, SF);
 
     BinaryOperator::Opcode Op = B->getOpcode();
 
@@ -68,7 +68,7 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* B,
       // Simulate the effects of a "store":  bind the value of the RHS
       // to the L-Value represented by the LHS.
       SVal ExprVal = B->isGLValue() ? LeftV : RightV;
-      evalStore(Tmp2, B, LHS, N, state->BindExpr(B, SF, ExprVal), LeftV,
+      evalStore(Tmp2, B, LHS, N, State->BindExpr(B, SF, ExprVal), LeftV,
                 RightV);
       continue;
     }
@@ -90,20 +90,20 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* 
B,
       // sure that the members of temporaries have a valid 'this' pointer for
       // other checks.
       if (B->getOpcode() == BO_PtrMemD)
-        state = createTemporaryRegionIfNeeded(state, SF, LHS);
+        State = createTemporaryRegionIfNeeded(State, SF, LHS);
 
       // Process non-assignments except commas or short-circuited
       // logical expressions (LAnd and LOr).
-      SVal Result = evalBinOp(state, Op, LeftV, RightV, B->getType());
+      SVal Result = evalBinOp(State, Op, LeftV, RightV, B->getType());
       if (!Result.isUnknown()) {
-        state = state->BindExpr(B, SF, Result);
+        State = State->BindExpr(B, SF, Result);
       } else {
         // If we cannot evaluate the operation escape the operands.
-        state = escapeValues(state, LeftV, PSK_EscapeOther);
-        state = escapeValues(state, RightV, PSK_EscapeOther);
+        State = escapeValues(State, LeftV, PSK_EscapeOther);
+        State = escapeValues(State, RightV, PSK_EscapeOther);
       }
 
-      Bldr.generateNode(B, N, state);
+      Bldr.generateNode(B, N, State);
       continue;
     }
 
@@ -128,12 +128,12 @@ void ExprEngine::VisitBinaryOperator(const 
BinaryOperator* B,
     // null dereferences, and so on.
     ExplodedNodeSet Tmp;
     SVal location = LeftV;
-    evalLoad(Tmp, B, LHS, N, state, location);
+    evalLoad(Tmp, B, LHS, N, State, location);
 
     for (ExplodedNode *N : Tmp) {
-      state = N->getState();
+      State = N->getState();
       const StackFrame *SF = N->getStackFrame();
-      SVal V = state->getSVal(LHS, SF);
+      SVal V = State->getSVal(LHS, SF);
 
       // Get the computation type.
       QualType CTy =
@@ -150,7 +150,7 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* 
B,
       V = svalBuilder.evalCast(V, CLHSTy, LTy);
 
       // Compute the result of the operation.
-      SVal Result = svalBuilder.evalCast(evalBinOp(state, Op, V, RightV, CTy),
+      SVal Result = svalBuilder.evalCast(evalBinOp(State, Op, V, RightV, CTy),
                                          B->getType(), CTy);
 
       SVal LHSVal;
@@ -173,11 +173,11 @@ void ExprEngine::VisitBinaryOperator(const 
BinaryOperator* B,
       // In C++, assignment and compound assignment operators return an
       // lvalue.
       if (B->isGLValue())
-        state = state->BindExpr(B, SF, location);
+        State = State->BindExpr(B, SF, location);
       else
-        state = state->BindExpr(B, SF, Result);
+        State = State->BindExpr(B, SF, Result);
 
-      evalStore(Tmp2, B, LHS, N, state, location, LHSVal);
+      evalStore(Tmp2, B, LHS, N, State, location, LHSVal);
     }
   }
 

From e16ed8e7c6bef1e47620091327001abb6f993f62 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]>
Date: Mon, 22 Jun 2026 18:32:58 +0200
Subject: [PATCH 06/12] Eliminate redundant variable 'location'

At this point the code switches to using 'location' as the new name of
'LeftV' which is confusing.
---
 clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 4e14062d27c39..0e32c18b32ffa 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -127,8 +127,7 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* 
B,
     // Perform a load (the LHS).  This performs the checks for
     // null dereferences, and so on.
     ExplodedNodeSet Tmp;
-    SVal location = LeftV;
-    evalLoad(Tmp, B, LHS, N, State, location);
+    evalLoad(Tmp, B, LHS, N, State, LeftV);
 
     for (ExplodedNode *N : Tmp) {
       State = N->getState();
@@ -153,7 +152,7 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* 
B,
       SVal Result = svalBuilder.evalCast(evalBinOp(State, Op, V, RightV, CTy),
                                          B->getType(), CTy);
 
-      SVal LHSVal;
+      SVal LHSVal; // Value that will be stored at location specifed by LeftV.
 
       if (Result.isUnknown()) {
         // The symbolic value is actually for the type of the left-hand side
@@ -173,11 +172,11 @@ void ExprEngine::VisitBinaryOperator(const 
BinaryOperator* B,
       // In C++, assignment and compound assignment operators return an
       // lvalue.
       if (B->isGLValue())
-        State = State->BindExpr(B, SF, location);
+        State = State->BindExpr(B, SF, LeftV);
       else
         State = State->BindExpr(B, SF, Result);
 
-      evalStore(Tmp2, B, LHS, N, State, location, LHSVal);
+      evalStore(Tmp2, B, LHS, N, State, LeftV, LHSVal);
     }
   }
 

From 0e812af949b24c45f4e66ba8f2672554d6c60175 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]>
Date: Mon, 22 Jun 2026 18:45:02 +0200
Subject: [PATCH 07/12] Use a self-documenting variable name

---
 clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 0e32c18b32ffa..63e2793dd1a8b 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -152,21 +152,21 @@ void ExprEngine::VisitBinaryOperator(const 
BinaryOperator* B,
       SVal Result = svalBuilder.evalCast(evalBinOp(State, Op, V, RightV, CTy),
                                          B->getType(), CTy);
 
-      SVal LHSVal; // Value that will be stored at location specifed by LeftV.
+      SVal StoredInLeftV;
 
       if (Result.isUnknown()) {
         // The symbolic value is actually for the type of the left-hand side
         // expression, not the computation type, as this is the value the
         // LValue on the LHS will bind to.
-        LHSVal = svalBuilder.conjureSymbolVal(/*symbolTag=*/nullptr,
-                                              getCFGElementRef(), SF, LTy,
-                                              getNumVisitedCurrent());
+        StoredInLeftV = svalBuilder.conjureSymbolVal(
+            /*symbolTag=*/nullptr, getCFGElementRef(), SF, LTy,
+            getNumVisitedCurrent());
         // However, we need to convert the symbol to the computation type.
-        Result = svalBuilder.evalCast(LHSVal, CTy, LTy);
+        Result = svalBuilder.evalCast(StoredInLeftV, CTy, LTy);
       } else {
         // The left-hand side may bind to a different value then the
         // computation type.
-        LHSVal = svalBuilder.evalCast(Result, LTy, CTy);
+        StoredInLeftV = svalBuilder.evalCast(Result, LTy, CTy);
       }
 
       // In C++, assignment and compound assignment operators return an
@@ -176,7 +176,7 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* 
B,
       else
         State = State->BindExpr(B, SF, Result);
 
-      evalStore(Tmp2, B, LHS, N, State, LeftV, LHSVal);
+      evalStore(Tmp2, B, LHS, N, State, LeftV, StoredInLeftV);
     }
   }
 

From ab9bda29f664335d5dd1624fb841e4d930514705 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]>
Date: Mon, 22 Jun 2026 18:45:29 +0200
Subject: [PATCH 08/12] Simplify getting the relevant types

---
 clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 63e2793dd1a8b..2d6594d7d2dce 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -134,15 +134,11 @@ void ExprEngine::VisitBinaryOperator(const 
BinaryOperator* B,
       const StackFrame *SF = N->getStackFrame();
       SVal V = State->getSVal(LHS, SF);
 
-      // Get the computation type.
-      QualType CTy =
-        cast<CompoundAssignOperator>(B)->getComputationResultType();
-      CTy = getContext().getCanonicalType(CTy);
-
-      QualType CLHSTy =
-        cast<CompoundAssignOperator>(B)->getComputationLHSType();
-      CLHSTy = getContext().getCanonicalType(CLHSTy);
-
+      // Determine the relevant types.
+      const ASTContext &ACtx = getContext();
+      const auto *CAOpB = cast<CompoundAssignOperator>(B);
+      QualType CTy = ACtx.getCanonicalType(CAOpB->getComputationResultType());
+      QualType CLHSTy = ACtx.getCanonicalType(CAOpB->getComputationLHSType());
       QualType LTy = getContext().getCanonicalType(LHS->getType());
 
       // Promote LHS.

From 99820f279d74d6e6e2cda382311f6963d73931c3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]>
Date: Mon, 22 Jun 2026 19:01:51 +0200
Subject: [PATCH 09/12] Replace verbose helper function with lambda

---
 clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp | 37 ++++++-------------
 1 file changed, 12 insertions(+), 25 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 2d6594d7d2dce..26b798fbfd87a 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -20,24 +20,6 @@ using namespace clang;
 using namespace ento;
 using llvm::APSInt;
 
-/// Optionally conjure and return a symbol for offset when processing
-/// \p Elem.
-/// If \p Other is a location, conjure a symbol for \p Symbol
-/// (offset) if it is unknown so that memory arithmetic always
-/// results in an ElementRegion.
-/// \p Count The number of times the current basic block was visited.
-static SVal conjureOffsetSymbolOnLocation(SVal Symbol, SVal Other,
-                                          ConstCFGElementRef Elem, QualType Ty,
-                                          SValBuilder &svalBuilder,
-                                          unsigned Count,
-                                          const StackFrame *SF) {
-  if (isa<Loc>(Other) && Ty->isIntegralOrEnumerationType() &&
-      Symbol.isUnknown()) {
-    return svalBuilder.conjureSymbolVal(Elem, SF, Ty, Count);
-  }
-  return Symbol;
-}
-
 void ExprEngine::VisitBinaryOperator(const BinaryOperator* B,
                                      ExplodedNode *Pred,
                                      ExplodedNodeSet &Dst) {
@@ -77,13 +59,18 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* 
B,
       NodeBuilder Bldr(N, Tmp2, *currBldrCtx);
 
       if (B->isAdditiveOp()) {
-        unsigned Count = getNumVisitedCurrent();
-        RightV = conjureOffsetSymbolOnLocation(
-            RightV, LeftV, getCFGElementRef(), RHS->getType(), svalBuilder,
-            Count, SF);
-        LeftV = conjureOffsetSymbolOnLocation(LeftV, RightV, 
getCFGElementRef(),
-                                              LHS->getType(), svalBuilder,
-                                              Count, SF);
+        // Ensure that if `p` is a pointer and `i` is an integer with Unknown
+        // value, then `p+i`, `i+p` and `p-i` are evaluated to element regions
+        // (with a symbolic offset) instead of Unknown.
+        auto ConjureIfNeeded = [this, SF](SVal &V, SVal Other, QualType VTy) {
+          if (isa<Loc>(Other) && VTy->isIntegralOrEnumerationType() &&
+              V.isUnknown()) {
+            V = svalBuilder.conjureSymbolVal(getCFGElementRef(), SF, VTy,
+                                             getNumVisitedCurrent());
+          }
+        };
+        ConjureIfNeeded(RightV, LeftV, RHS->getType());
+        ConjureIfNeeded(LeftV, RightV, LHS->getType());
       }
 
       // Although we don't yet model pointers-to-members, we do need to make

From 98db32fc849bf8ee25530596c14790ba15540586 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]>
Date: Mon, 22 Jun 2026 19:09:57 +0200
Subject: [PATCH 10/12] Remove the NodeBuilder from VisitBinaryOperator

This was a very trivial `NodeBuilder` that unconditionally generated
exactly one node. (Its constructor was inserting `N` into `Tmp2` but
this was irrelevant because the `generateNode` cancelled it out.)
---
 clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 26b798fbfd87a..c8e5343b1fc16 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -56,8 +56,6 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* B,
     }
 
     if (!B->isAssignmentOp()) {
-      NodeBuilder Bldr(N, Tmp2, *currBldrCtx);
-
       if (B->isAdditiveOp()) {
         // Ensure that if `p` is a pointer and `i` is an integer with Unknown
         // value, then `p+i`, `i+p` and `p-i` are evaluated to element regions
@@ -90,7 +88,7 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* B,
         State = escapeValues(State, RightV, PSK_EscapeOther);
       }
 
-      Bldr.generateNode(B, N, State);
+      Tmp2.insert(Engine.makePostStmtNode(B, State, N));
       continue;
     }
 

From 3ed15379174b6520b459ed1c45e59f91c682d62d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]>
Date: Mon, 22 Jun 2026 19:13:33 +0200
Subject: [PATCH 11/12] Declare StackFrame *SF at top of method

The relevant StackFrame only changes when the analysis enters or leaves
an inlined function call, so we can query the same `SF` from any
reasonably recent exploded node.

As this boilerplate definition does not carry useful information, I
prefer to place it at the very beginning of the method.
---
 clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index c8e5343b1fc16..96238b0ddcd05 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -23,6 +23,7 @@ using llvm::APSInt;
 void ExprEngine::VisitBinaryOperator(const BinaryOperator* B,
                                      ExplodedNode *Pred,
                                      ExplodedNodeSet &Dst) {
+  const StackFrame *SF = Pred->getStackFrame();
 
   Expr *LHS = B->getLHS()->IgnoreParens();
   Expr *RHS = B->getRHS()->IgnoreParens();
@@ -35,7 +36,6 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* B,
   // With both the LHS and RHS evaluated, process the operation itself.
   for (ExplodedNode *N : CheckedSet) {
     ProgramStateRef State = N->getState();
-    const StackFrame *SF = N->getStackFrame();
     SVal LeftV = State->getSVal(LHS, SF);
     SVal RightV = State->getSVal(RHS, SF);
 
@@ -116,7 +116,6 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* 
B,
 
     for (ExplodedNode *N : Tmp) {
       State = N->getState();
-      const StackFrame *SF = N->getStackFrame();
       SVal V = State->getSVal(LHS, SF);
 
       // Determine the relevant types.

From 3c5b0e9a4540a402cb4cd2d2d9b3124045e1fc42 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]>
Date: Tue, 30 Jun 2026 13:16:16 +0200
Subject: [PATCH 12/12] Use `ACtx` to refer to the ASTContext

---
 clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 96238b0ddcd05..33c31fe10782a 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -123,7 +123,7 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* 
B,
       const auto *CAOpB = cast<CompoundAssignOperator>(B);
       QualType CTy = ACtx.getCanonicalType(CAOpB->getComputationResultType());
       QualType CLHSTy = ACtx.getCanonicalType(CAOpB->getComputationLHSType());
-      QualType LTy = getContext().getCanonicalType(LHS->getType());
+      QualType LTy = ACtx.getCanonicalType(LHS->getType());
 
       // Promote LHS.
       V = svalBuilder.evalCast(V, CLHSTy, LTy);

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to