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
