https://github.com/NagyDonat created 
https://github.com/llvm/llvm-project/pull/237160

In the special case when the same symbol appeared on both sides of the 
top-level operator (perhaps with some integer offsets), it was cancelled out... 
EVEN WHEN THE OPERATOR WAS ADDITION!

E.g. it was rearranging `(x + 1) + (x + 2)` to `3` and `x + x` to zero.

This change skips the "cancel out symbol" step for `BO_Add`, which ensures that 
e.g. `(x + 1) + (x + 2)` is rearranged to `(x + x) + 3`.

Perhaps later we should rearrange the `(x + x)` part to `x * 2`, but I don't 
see any concrete benefits from this.

Reported-by: Arseniy Zaostrovnykh <[email protected]>

From 748120c0c6dee61f2e03765d699750056ec57586 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]>
Date: Fri, 30 Oct 2026 10:44:06 +0100
Subject: [PATCH] [analyzer] Fix an ugly bug in tryRearrange logic

In the special case when the same symbol appeared on both sides of the
top-level operator (perhaps with some integer offsets), it was cancelled
out... EVEN WHEN THE OPERATOR WAS ADDITION!

E.g. it was rearranging `(x + 1) + (x + 2)` to `3` and `x + x` to zero.

This change skips the "cancel out" symbol step for `BO_Add`, which
ensures that e.g. `(x + 1) + (x + 2)` is rearranged to `(x + x) + 3`.

Perhaps later we should rearrange the `(x + x)` part to `x * 2`, but
I don't see any concrete benefits from this.

Reported-by: Arseniy Zaostrovnykh <[email protected]>
---
 clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp      | 2 +-
 .../test/Analysis/svalbuilder-rearrange-comparisons.cpp  | 9 +++++++++
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp 
b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
index c89271af525b8e..881cff258c0ab2 100644
--- a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -346,7 +346,7 @@ static std::optional<NonLoc> tryRearrange(ProgramStateRef 
State,
   if (BinaryOperator::isComparisonOp(Op) && !InBounds(LInt, RInt, LSym, RSym))
     return std::nullopt;
 
-  if (LSym == RSym)
+  if (LSym == RSym && Op != BO_Add)
     return SVB
         .evalBinOpNN(State, Op, nonloc::ConcreteInt(BV.getValue(LInt)),
                      nonloc::ConcreteInt(BV.getValue(RInt)), ResultTy)
diff --git a/clang/test/Analysis/svalbuilder-rearrange-comparisons.cpp 
b/clang/test/Analysis/svalbuilder-rearrange-comparisons.cpp
index eca6ab0c71befe..95cdefa4b49df6 100644
--- a/clang/test/Analysis/svalbuilder-rearrange-comparisons.cpp
+++ b/clang/test/Analysis/svalbuilder-rearrange-comparisons.cpp
@@ -1026,3 +1026,12 @@ void unsigned_concrete_int_no_crash(void) {
   clang_analyzer_express(y); // expected-warning {{$y}}
   clang_analyzer_express(x == y); // expected-warning {{$x + 1U == $y + 1U}}
 }
+
+void add_shifted_same_symbol(void) {
+  int x = f();
+  clang_analyzer_denote(x, "$x");
+  clang_analyzer_express((x + 1) + (x + 2)); // expected-warning{{$x + $x + 3}}
+  clang_analyzer_express((x + 1) + x); // expected-warning{{$x + $x + 1}}
+  clang_analyzer_express((x - 1) + (x + 1)); // expected-warning{{$x + $x}}
+  clang_analyzer_express(x + x); // expected-warning{{$x + $x}}
+}

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

Reply via email to