https://github.com/NagyDonat updated https://github.com/llvm/llvm-project/pull/233441
From 6226e85b1d0c39695146d1b1ce5ecaf83916e5c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]> Date: Fri, 16 Oct 2026 13:00:48 +0200 Subject: [PATCH 01/10] Remove an obsolete comment This is leftover from an earlier version of the code where `SingleTy` was initialized later. See https://reviews.llvm.org/D41938?id=130403 --- clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp index d8fe3b32b6f1a1..1a20002fea17a7 100644 --- a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -394,7 +394,6 @@ static std::optional<NonLoc> tryRearrange(ProgramStateRef State, SingleTy = LSym->getType(); if (ResultTy != SVB.getConditionType()) return std::nullopt; - // Initialize SingleTy later with a symbol's type. } else if (BinaryOperator::isAdditiveOp(Op)) { SingleTy = ResultTy; if (LSym->getType() != SingleTy) From 459663a9917671075e5018cb152c1385829c7dc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]> Date: Fri, 16 Oct 2026 13:04:57 +0200 Subject: [PATCH 02/10] Simplify initialization of SingleTy --- clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp index 1a20002fea17a7..a8217496b36052 100644 --- a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -379,9 +379,6 @@ static std::optional<NonLoc> tryRearrange(ProgramStateRef State, ProgramStateManager &StateMgr = State->getStateManager(); SValBuilder &SVB = StateMgr.getSValBuilder(); - // We expect everything to be of the same type - this type. - QualType SingleTy; - // FIXME: This should be enabled by default, at least for additive operations. if (!SVB.getAnalyzerOptions().ShouldAggressivelySimplifyBinaryOperation) return std::nullopt; @@ -390,13 +387,14 @@ static std::optional<NonLoc> tryRearrange(ProgramStateRef State, if (!LSym) return std::nullopt; + // We expect everything to be of the same type - this type. + QualType SingleTy = LSym->getType(); + if (BinaryOperator::isComparisonOp(Op)) { - SingleTy = LSym->getType(); if (ResultTy != SVB.getConditionType()) return std::nullopt; } else if (BinaryOperator::isAdditiveOp(Op)) { - SingleTy = ResultTy; - if (LSym->getType() != SingleTy) + if (ResultTy != SingleTy) return std::nullopt; } else { // Don't rearrange other operations. From 4225879f782529d7861e77d6402df55b4c0d4f4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]> Date: Fri, 16 Oct 2026 13:09:02 +0200 Subject: [PATCH 03/10] Remove a redundant assertion `SingleTy` is always defined as `LSym->getType()` and constructors of symbol classes assert that `isValidTypeForSymbol()` holds for the type of the symbol, which implies that the type is not a null `QualType`. The assertion was leftover from older variants where the initialization of `SingleTy` was more complex. --- clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp index a8217496b36052..64c4be6d2d3079 100644 --- a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -401,8 +401,6 @@ static std::optional<NonLoc> tryRearrange(ProgramStateRef State, return std::nullopt; } - assert(!SingleTy.isNull() && "We should have figured out the type by now!"); - // Rearrange signed symbolic expressions only // FIXME: This should also handle unsigned, at least for additive operations. if (!SingleTy->isSignedIntegerOrEnumerationType()) From 1d6b91e76eef8c2502a247fe16404f25317f0b96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]> Date: Fri, 16 Oct 2026 15:54:13 +0200 Subject: [PATCH 04/10] Inline and rephrase shouldRearrange logic --- .../StaticAnalyzer/Core/SimpleSValBuilder.cpp | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp index 64c4be6d2d3079..19cff15a42bf3d 100644 --- a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -265,7 +265,7 @@ static bool isWithinConstantOverflowBounds(SymbolRef Sym, } // Same for the concrete integers: see if I is within [min/4, max/4]. -static bool isWithinConstantOverflowBounds(llvm::APSInt I) { +static bool isWithinConstantOverflowBounds(llvm::APSInt I, ProgramStateRef) { APSIntType AT(I); assert(!AT.isUnsigned() && "This only works with signed integers!"); @@ -362,17 +362,6 @@ static SVal doRearrangeUnchecked(ProgramStateRef State, return UnknownVal(); } -// Rearrange if symbol type matches the result type and if the operator is a -// comparison operator, both symbol and constant must be within constant -// overflow bounds. -static bool shouldRearrange(ProgramStateRef State, BinaryOperator::Opcode Op, - SymbolRef Sym, llvm::APSInt Int, QualType Ty) { - return Sym->getType() == Ty && - (!BinaryOperator::isComparisonOp(Op) || - (isWithinConstantOverflowBounds(Sym, State) && - isWithinConstantOverflowBounds(Int))); -} - static std::optional<NonLoc> tryRearrange(ProgramStateRef State, BinaryOperator::Opcode Op, NonLoc Lhs, NonLoc Rhs, QualType ResultTy) { @@ -414,8 +403,14 @@ static std::optional<NonLoc> tryRearrange(ProgramStateRef State, llvm::APSInt LInt, RInt; std::tie(LSym, LInt) = decomposeSymbol(LSym, BV); std::tie(RSym, RInt) = decomposeSymbol(RSym, BV); - if (!shouldRearrange(State, Op, LSym, LInt, SingleTy) || - !shouldRearrange(State, Op, RSym, RInt, SingleTy)) + + if (LSym->getType() != SingleTy || RSym->getType() != SingleTy) + return std::nullopt; + + auto InBounds = [State](auto... X) { + return (... && isWithinConstantOverflowBounds(X, State)); + }; + if (BinaryOperator::isComparisonOp(Op) && !InBounds(LInt, RInt, LSym, RSym)) return std::nullopt; // We know that no overflows can occur anymore. From e8f764468c0913d48fefdbbae5a878da51f56af4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]> Date: Fri, 16 Oct 2026 16:09:38 +0200 Subject: [PATCH 05/10] Move doRearrangeUnchecked after tryRearrange This moves the code without any changes to prepare for further simplifications. --- .../StaticAnalyzer/Core/SimpleSValBuilder.cpp | 115 +++++++++--------- 1 file changed, 60 insertions(+), 55 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp index 19cff15a42bf3d..e9213b1d191e56 100644 --- a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -287,6 +287,66 @@ static std::pair<SymbolRef, APSIntPtr> decomposeSymbol(SymbolRef Sym, return std::make_pair(Sym, BV.getValue(0, Sym->getType())); } +static SVal doRearrangeUnchecked(ProgramStateRef State, + BinaryOperator::Opcode Op, SymbolRef LSym, + llvm::APSInt LInt, SymbolRef RSym, + llvm::APSInt RInt); + +static std::optional<NonLoc> tryRearrange(ProgramStateRef State, + BinaryOperator::Opcode Op, NonLoc Lhs, + NonLoc Rhs, QualType ResultTy) { + ProgramStateManager &StateMgr = State->getStateManager(); + SValBuilder &SVB = StateMgr.getSValBuilder(); + + // FIXME: This should be enabled by default, at least for additive operations. + if (!SVB.getAnalyzerOptions().ShouldAggressivelySimplifyBinaryOperation) + return std::nullopt; + + SymbolRef LSym = Lhs.getAsSymbol(); + if (!LSym) + return std::nullopt; + + // We expect everything to be of the same type - this type. + QualType SingleTy = LSym->getType(); + + if (BinaryOperator::isComparisonOp(Op)) { + if (ResultTy != SVB.getConditionType()) + return std::nullopt; + } else if (BinaryOperator::isAdditiveOp(Op)) { + if (ResultTy != SingleTy) + return std::nullopt; + } else { + // Don't rearrange other operations. + return std::nullopt; + } + + // Rearrange signed symbolic expressions only + // FIXME: This should also handle unsigned, at least for additive operations. + if (!SingleTy->isSignedIntegerOrEnumerationType()) + return std::nullopt; + + SymbolRef RSym = Rhs.getAsSymbol(); + if (!RSym || RSym->getType() != SingleTy) + return std::nullopt; + + BasicValueFactory &BV = State->getBasicVals(); + llvm::APSInt LInt, RInt; + std::tie(LSym, LInt) = decomposeSymbol(LSym, BV); + std::tie(RSym, RInt) = decomposeSymbol(RSym, BV); + + if (LSym->getType() != SingleTy || RSym->getType() != SingleTy) + return std::nullopt; + + auto InBounds = [State](auto... X) { + return (... && isWithinConstantOverflowBounds(X, State)); + }; + if (BinaryOperator::isComparisonOp(Op) && !InBounds(LInt, RInt, LSym, RSym)) + return std::nullopt; + + // We know that no overflows can occur anymore. + return doRearrangeUnchecked(State, Op, LSym, LInt, RSym, RInt) + .getAs<NonLoc>(); +} // Simplify "(LSym + LInt) Op (RSym + RInt)" assuming all values are of the // same signed integral type and no overflows occur (which should be checked // by the caller). May return UnknownVal if the symbol complexity threshold is @@ -362,61 +422,6 @@ static SVal doRearrangeUnchecked(ProgramStateRef State, return UnknownVal(); } -static std::optional<NonLoc> tryRearrange(ProgramStateRef State, - BinaryOperator::Opcode Op, NonLoc Lhs, - NonLoc Rhs, QualType ResultTy) { - ProgramStateManager &StateMgr = State->getStateManager(); - SValBuilder &SVB = StateMgr.getSValBuilder(); - - // FIXME: This should be enabled by default, at least for additive operations. - if (!SVB.getAnalyzerOptions().ShouldAggressivelySimplifyBinaryOperation) - return std::nullopt; - - SymbolRef LSym = Lhs.getAsSymbol(); - if (!LSym) - return std::nullopt; - - // We expect everything to be of the same type - this type. - QualType SingleTy = LSym->getType(); - - if (BinaryOperator::isComparisonOp(Op)) { - if (ResultTy != SVB.getConditionType()) - return std::nullopt; - } else if (BinaryOperator::isAdditiveOp(Op)) { - if (ResultTy != SingleTy) - return std::nullopt; - } else { - // Don't rearrange other operations. - return std::nullopt; - } - - // Rearrange signed symbolic expressions only - // FIXME: This should also handle unsigned, at least for additive operations. - if (!SingleTy->isSignedIntegerOrEnumerationType()) - return std::nullopt; - - SymbolRef RSym = Rhs.getAsSymbol(); - if (!RSym || RSym->getType() != SingleTy) - return std::nullopt; - - BasicValueFactory &BV = State->getBasicVals(); - llvm::APSInt LInt, RInt; - std::tie(LSym, LInt) = decomposeSymbol(LSym, BV); - std::tie(RSym, RInt) = decomposeSymbol(RSym, BV); - - if (LSym->getType() != SingleTy || RSym->getType() != SingleTy) - return std::nullopt; - - auto InBounds = [State](auto... X) { - return (... && isWithinConstantOverflowBounds(X, State)); - }; - if (BinaryOperator::isComparisonOp(Op) && !InBounds(LInt, RInt, LSym, RSym)) - return std::nullopt; - - // We know that no overflows can occur anymore. - return doRearrangeUnchecked(State, Op, LSym, LInt, RSym, RInt) - .getAs<NonLoc>(); -} SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state, BinaryOperator::Opcode op, From 8eafb8d6d113e00e0d56d932ed635bb9ea733544 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]> Date: Fri, 16 Oct 2026 16:12:13 +0200 Subject: [PATCH 06/10] Let doRearrangeUnchecked return optional<NonLoc> This prepares the ground for inlining this function to get rid of lots of code duplication. --- .../StaticAnalyzer/Core/SimpleSValBuilder.cpp | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp index e9213b1d191e56..d2d36c7563af69 100644 --- a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -287,10 +287,10 @@ static std::pair<SymbolRef, APSIntPtr> decomposeSymbol(SymbolRef Sym, return std::make_pair(Sym, BV.getValue(0, Sym->getType())); } -static SVal doRearrangeUnchecked(ProgramStateRef State, - BinaryOperator::Opcode Op, SymbolRef LSym, - llvm::APSInt LInt, SymbolRef RSym, - llvm::APSInt RInt); +static std::optional<NonLoc> +doRearrangeUnchecked(ProgramStateRef State, BinaryOperator::Opcode Op, + SymbolRef LSym, llvm::APSInt LInt, SymbolRef RSym, + llvm::APSInt RInt); static std::optional<NonLoc> tryRearrange(ProgramStateRef State, BinaryOperator::Opcode Op, NonLoc Lhs, @@ -344,17 +344,16 @@ static std::optional<NonLoc> tryRearrange(ProgramStateRef State, return std::nullopt; // We know that no overflows can occur anymore. - return doRearrangeUnchecked(State, Op, LSym, LInt, RSym, RInt) - .getAs<NonLoc>(); + return doRearrangeUnchecked(State, Op, LSym, LInt, RSym, RInt); } // Simplify "(LSym + LInt) Op (RSym + RInt)" assuming all values are of the // same signed integral type and no overflows occur (which should be checked // by the caller). May return UnknownVal if the symbol complexity threshold is // reached. -static SVal doRearrangeUnchecked(ProgramStateRef State, - BinaryOperator::Opcode Op, SymbolRef LSym, - llvm::APSInt LInt, SymbolRef RSym, - llvm::APSInt RInt) { +static std::optional<NonLoc> +doRearrangeUnchecked(ProgramStateRef State, BinaryOperator::Opcode Op, + SymbolRef LSym, llvm::APSInt LInt, SymbolRef RSym, + llvm::APSInt RInt) { SValBuilder &SVB = State->getStateManager().getSValBuilder(); BasicValueFactory &BV = SVB.getBasicValueFactory(); @@ -378,7 +377,7 @@ static SVal doRearrangeUnchecked(ProgramStateRef State, return SVB .evalBinOpNN(State, Op, nonloc::ConcreteInt(BV.getValue(LInt)), nonloc::ConcreteInt(BV.getValue(RInt)), ResultTy) - .castAs<NonLoc>(); + .getAs<NonLoc>(); auto MakeSymExprVal = [&SVB, SymTy](SymbolRef Lhs, BinaryOperatorKind Op, SymbolRef Rhs) { @@ -412,17 +411,17 @@ static SVal doRearrangeUnchecked(ProgramStateRef State, ResultOp = BO_Sub; } else if (ResultInt == 0) { // Shortcut: Simplify "$x + 0" to "$x". - return ResultSV; + return ResultSV.getAs<NonLoc>(); } } if (auto ResultNL = ResultSV.getAs<NonLoc>()) { nonloc::ConcreteInt ResultCI(BV.getValue(ResultInt)); - return SVB.makeSymExprValNN(ResultOp, *ResultNL, ResultCI, ResultTy); + return SVB.makeSymExprValNN(ResultOp, *ResultNL, ResultCI, ResultTy) + .getAs<NonLoc>(); } - return UnknownVal(); + return std::nullopt; } - SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state, BinaryOperator::Opcode op, NonLoc lhs, NonLoc rhs, From 8b37d88fa2fcb62b4926563a5245252985ef7809 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]> Date: Fri, 16 Oct 2026 16:17:37 +0200 Subject: [PATCH 07/10] Inline doRearrangeUnchecked into tryRearrange The combination of these functions is admittedly a bit long (although much longer functions also exist in the codebase), but they clearly form a single logical unit and joining them lets us eliminate lots of redundant logic. In my opinion the code is much easier to read this way. --- .../StaticAnalyzer/Core/SimpleSValBuilder.cpp | 35 ++++--------------- 1 file changed, 6 insertions(+), 29 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp index d2d36c7563af69..04e722803edc01 100644 --- a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -287,11 +287,10 @@ static std::pair<SymbolRef, APSIntPtr> decomposeSymbol(SymbolRef Sym, return std::make_pair(Sym, BV.getValue(0, Sym->getType())); } -static std::optional<NonLoc> -doRearrangeUnchecked(ProgramStateRef State, BinaryOperator::Opcode Op, - SymbolRef LSym, llvm::APSInt LInt, SymbolRef RSym, - llvm::APSInt RInt); - +// Simplify "(LSym + LInt) Op (RSym + RInt)" when all values are of the +// same signed integral type and no overflows occurs. Returns the simplified +// value or std::nullopt when the the preconditions are not satisfied or the +// symbol complexity limit is reached. static std::optional<NonLoc> tryRearrange(ProgramStateRef State, BinaryOperator::Opcode Op, NonLoc Lhs, NonLoc Rhs, QualType ResultTy) { @@ -343,36 +342,14 @@ static std::optional<NonLoc> tryRearrange(ProgramStateRef State, if (BinaryOperator::isComparisonOp(Op) && !InBounds(LInt, RInt, LSym, RSym)) return std::nullopt; - // We know that no overflows can occur anymore. - return doRearrangeUnchecked(State, Op, LSym, LInt, RSym, RInt); -} -// Simplify "(LSym + LInt) Op (RSym + RInt)" assuming all values are of the -// same signed integral type and no overflows occur (which should be checked -// by the caller). May return UnknownVal if the symbol complexity threshold is -// reached. -static std::optional<NonLoc> -doRearrangeUnchecked(ProgramStateRef State, BinaryOperator::Opcode Op, - SymbolRef LSym, llvm::APSInt LInt, SymbolRef RSym, - llvm::APSInt RInt) { - SValBuilder &SVB = State->getStateManager().getSValBuilder(); - BasicValueFactory &BV = SVB.getBasicValueFactory(); + QualType SymTy = SingleTy; // TODO eliminate this - QualType SymTy = LSym->getType(); - assert(SymTy == RSym->getType() && - "Symbols are not of the same type!"); + // FIXME: Why can we assert these? assert(APSIntType(LInt) == BV.getAPSIntType(SymTy) && "Integers are not of the same type as symbols!"); assert(APSIntType(RInt) == BV.getAPSIntType(SymTy) && "Integers are not of the same type as symbols!"); - QualType ResultTy; - if (BinaryOperator::isComparisonOp(Op)) - ResultTy = SVB.getConditionType(); - else if (BinaryOperator::isAdditiveOp(Op)) - ResultTy = SymTy; - else - llvm_unreachable("Operation not suitable for unchecked rearrangement!"); - if (LSym == RSym) return SVB .evalBinOpNN(State, Op, nonloc::ConcreteInt(BV.getValue(LInt)), From bfba49bf0ff48dc90a3f602fd42006e1004e1f3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]> Date: Mon, 19 Oct 2026 15:52:27 +0200 Subject: [PATCH 08/10] Rename SingleTy to CommonTy `SingleTy` was already acceptable, but I felt that `CommonTy` more accurately reflects the role of this variable -- so I renamed it before spreading the name to the second half of the function which now uses `SymTy` for the same role. --- clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp index 04e722803edc01..1a6c8029e3bceb 100644 --- a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -306,13 +306,13 @@ static std::optional<NonLoc> tryRearrange(ProgramStateRef State, return std::nullopt; // We expect everything to be of the same type - this type. - QualType SingleTy = LSym->getType(); + QualType CommonTy = LSym->getType(); if (BinaryOperator::isComparisonOp(Op)) { if (ResultTy != SVB.getConditionType()) return std::nullopt; } else if (BinaryOperator::isAdditiveOp(Op)) { - if (ResultTy != SingleTy) + if (ResultTy != CommonTy) return std::nullopt; } else { // Don't rearrange other operations. @@ -321,11 +321,11 @@ static std::optional<NonLoc> tryRearrange(ProgramStateRef State, // Rearrange signed symbolic expressions only // FIXME: This should also handle unsigned, at least for additive operations. - if (!SingleTy->isSignedIntegerOrEnumerationType()) + if (!CommonTy->isSignedIntegerOrEnumerationType()) return std::nullopt; SymbolRef RSym = Rhs.getAsSymbol(); - if (!RSym || RSym->getType() != SingleTy) + if (!RSym || RSym->getType() != CommonTy) return std::nullopt; BasicValueFactory &BV = State->getBasicVals(); @@ -333,7 +333,7 @@ static std::optional<NonLoc> tryRearrange(ProgramStateRef State, std::tie(LSym, LInt) = decomposeSymbol(LSym, BV); std::tie(RSym, RInt) = decomposeSymbol(RSym, BV); - if (LSym->getType() != SingleTy || RSym->getType() != SingleTy) + if (LSym->getType() != CommonTy || RSym->getType() != CommonTy) return std::nullopt; auto InBounds = [State](auto... X) { @@ -342,7 +342,7 @@ static std::optional<NonLoc> tryRearrange(ProgramStateRef State, if (BinaryOperator::isComparisonOp(Op) && !InBounds(LInt, RInt, LSym, RSym)) return std::nullopt; - QualType SymTy = SingleTy; // TODO eliminate this + QualType SymTy = CommonTy; // TODO eliminate this // FIXME: Why can we assert these? assert(APSIntType(LInt) == BV.getAPSIntType(SymTy) && From acb0cb15e78cf09f943758fb8d2fbadfbdfa92e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]> Date: Mon, 19 Oct 2026 15:55:23 +0200 Subject: [PATCH 09/10] Also use CommonTy in the second half of the function --- clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp index 1a6c8029e3bceb..5b9b00b6b64666 100644 --- a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -342,12 +342,10 @@ static std::optional<NonLoc> tryRearrange(ProgramStateRef State, if (BinaryOperator::isComparisonOp(Op) && !InBounds(LInt, RInt, LSym, RSym)) return std::nullopt; - QualType SymTy = CommonTy; // TODO eliminate this - // FIXME: Why can we assert these? - assert(APSIntType(LInt) == BV.getAPSIntType(SymTy) && + assert(APSIntType(LInt) == BV.getAPSIntType(CommonTy) && "Integers are not of the same type as symbols!"); - assert(APSIntType(RInt) == BV.getAPSIntType(SymTy) && + assert(APSIntType(RInt) == BV.getAPSIntType(CommonTy) && "Integers are not of the same type as symbols!"); if (LSym == RSym) @@ -356,10 +354,10 @@ static std::optional<NonLoc> tryRearrange(ProgramStateRef State, nonloc::ConcreteInt(BV.getValue(RInt)), ResultTy) .getAs<NonLoc>(); - auto MakeSymExprVal = [&SVB, SymTy](SymbolRef Lhs, BinaryOperatorKind Op, - SymbolRef Rhs) { + auto MakeSymExprVal = [&SVB, CommonTy](SymbolRef Lhs, BinaryOperatorKind Op, + SymbolRef Rhs) { return SVB.makeSymExprValNN(Op, nonloc::SymbolVal(Lhs), - nonloc::SymbolVal(Rhs), SymTy); + nonloc::SymbolVal(Rhs), CommonTy); }; SVal ResultSV = UnknownVal(); From 693efee53cb003f238087baf0823f94ff296ceb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]> Date: Tue, 20 Oct 2026 13:58:34 +0200 Subject: [PATCH 10/10] Fix typos in comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Balázs Benics <[email protected]> --- clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp index 5b9b00b6b64666..f0c7a91f6ea0f6 100644 --- a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -288,8 +288,8 @@ static std::pair<SymbolRef, APSIntPtr> decomposeSymbol(SymbolRef Sym, } // Simplify "(LSym + LInt) Op (RSym + RInt)" when all values are of the -// same signed integral type and no overflows occurs. Returns the simplified -// value or std::nullopt when the the preconditions are not satisfied or the +// same signed integral type and no overflow occurs. Returns the simplified +// value or std::nullopt when the preconditions are not satisfied or the // symbol complexity limit is reached. static std::optional<NonLoc> tryRearrange(ProgramStateRef State, BinaryOperator::Opcode Op, NonLoc Lhs, @@ -319,7 +319,7 @@ static std::optional<NonLoc> tryRearrange(ProgramStateRef State, return std::nullopt; } - // Rearrange signed symbolic expressions only + // Rearrange signed symbolic expressions only. // FIXME: This should also handle unsigned, at least for additive operations. if (!CommonTy->isSignedIntegerOrEnumerationType()) return std::nullopt; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
