[PATCH] D112621: [analyzer][solver] Introduce reasoning for not equal to operator

Balázs Benics via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Nov 25 08:53:16 PST 2022


steakhal added a comment.

I haven't looked at the implementation. I only checked the tests and something is not quite right there. See my comments inline.
BTW the line-coverage is good. I found only two branches which I want to have tests for - see inline.



================
Comment at: clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp:1624
+  if (LHS.isEmpty() || RHS.isEmpty())
+    return RangeFactory.getEmptySet();
+
----------------
This branch is uncovered by tests.


================
Comment at: clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp:1633
+    APSIntType CastingType(std::max(LHS.getBitWidth(), RHS.getBitWidth()),
+                           LHS.isUnsigned() || RHS.isUnsigned());
+
----------------
Although the `RHS.isUnsigned()` is covered 2 times in the `check-clang-analysis`target, I think it would make sense to have a dedicated test for this case in the `constant-folding.c`.


================
Comment at: clang/test/Analysis/constant-folding.c:289-301
+  if (u1 > INT_MAX && u1 <= UINT_MAX / 2 + 4 && u1 != UINT_MAX / 2 + 2 &&
+      u1 != UINT_MAX / 2 + 3 && s1 >= INT_MIN + 1 && s1 <= INT_MIN + 2) {
+    // u1: [INT_MAX+1, INT_MAX+1]U[INT_MAX+4, INT_MAX+4],
+    // s1: [INT_MIN+1, INT_MIN+2]
+    clang_analyzer_eval(u1 != s1); // expected-warning{{TRUE}}
+  }
+
----------------
These two hunks seem to be the same. We should probably keep one.
In addition to that, clang thinks the answer for `u1 != s1` depends on the operands.
We should probably return `UNKNOWN` for such cases. https://godbolt.org/z/aG1oY5Mr4


================
Comment at: clang/test/Analysis/constant-folding.c:315-319
+  if (s1 < 1 && s1 > -6 && s1 != -4 && s1 != -3 &&
+      u1 > UINT_MAX - 4 && u1 < UINT_MAX - 1) {
+    // s1: [-5, -5]U[-2, 0], u1: [UINT_MAX - 3, UINT_MAX - 2]
+    clang_analyzer_eval(u1 != s1); // expected-warning{{TRUE}}
+  }
----------------
Clang thinks it depends on the operands if `u1 != s1` is true.
https://godbolt.org/z/Pf3eYKnzd


================
Comment at: clang/test/Analysis/constant-folding.c:321-325
+  if (s1 < 1 && s1 > -7 && s1 != -4 && s1 != -3 &&
+      u1 > UINT_MAX - 4 && u1 < UINT_MAX - 1) {
+    // s1: [-6, -5]U[-2, 0], u1: [UINT_MAX - 3, UINT_MAX - 2]
+    clang_analyzer_eval(u1 != s1); // expected-warning{{TRUE}}
+  }
----------------
Clang thinks it depends on the operands if `u1 != s1` is true.
https://godbolt.org/z/1YYcd1EY8


================
Comment at: clang/test/Analysis/constant-folding.c:328-332
+  if (((u1 >= 1 && u1 <= 2) || (u1 >= 8 && u1 <= 9)) &&
+      u2 >= 5 && u2 <= 6) {
+    // u1: [1, 2]U[8, 9], u2: [5, 6]
+    clang_analyzer_eval(u1 != u2); // expected-warning{{TRUE}}
+  }
----------------
Clang thinks it depends on the operands if `u1 != u2` is true.
I believe, in such cases we should have returned `UNKNOWN`: https://godbolt.org/z/fxaT7YYob


================
Comment at: clang/test/Analysis/constant-folding.c:404-407
+  if (uch > 1 && sch < 1) {
+    // uch: [2, CHAR_MAX], sch: [SCHAR_MIN, 0]
+    clang_analyzer_eval(uch != sch); // expected-warning{{UNKNOWN}}
+  }
----------------
Shouldn't it print `TRUE`?
Clang will optimize this to `return true`. https://godbolt.org/z/6c6EPYofY
We should probably conclude the same here.


================
Comment at: clang/test/Analysis/constant-folding.c:420-423
+  if (ush > 1 && ssh < 1) {
+    // ush: [2, USHRT_MAX], ssh: [SHRT_MIN, 0]
+    clang_analyzer_eval(ush != ssh); // expected-warning{{UNKNOWN}}
+  }
----------------
It should return `TRUE`. https://godbolt.org/z/44Pax16d1


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D112621/new/

https://reviews.llvm.org/D112621



More information about the cfe-commits mailing list