manas added a comment.

> I also would like to see tests where the ranges are not going all the way to 
> either INT_MIN or INT_MAX (if we talk about int), but overflow still might 
> happen, and cases where overflow might happen, but we still can identify the 
> overflowing results precisely (e.g. the result is `[INT_MIN, INT_MIN + 10] 
> and [INT_MAX - 5, INT_MAX]`)

If I understood correctly, does a case like: `c, d in [INT_MAX/2 - 10, 
INT_MAX/2 + 10]` works? It will produce an overflowing range of `[INT_MIN, 
INT_MIN + 18] U [INT_MAX - 21, INT_MAX]`. I will add that to the test-set, if 
that is so.

For now, I have added tests for residual paths and negations of particular 
values, and edited buggy tests.



================
Comment at: clang/test/Analysis/constant-folding.c:282
+
+    if (c >= -20 && d >= -40) {
+      clang_analyzer_eval((c + d) < -1); // expected-warning{{TRUE}}
----------------
vsavchenko wrote:
> Great, it's good to check negative numbers.
> I have one note here.  The fact that we don't have a testing framework and 
> use this approach of inspecting the actual analysis has an interesting 
> implication.
> 
> ```
> if (a == 10) { // here we split path into 2 paths: one where a == 10, and one 
> where a != 10;
>                // one goes inside of if, one doesn't
>   . . .
> }
> if (a >= 5) { // here we split into 3 paths: a == 10, a < 5, and a in [5, 9] 
> and [11, INT_MAX] (aka a >= 5 and a != 10).
>               // 1 path was infeasible: a == 10 and a < 5
>               // Two of these paths go inside of the if, one doesn't
>   . . .
>   clang_analyzer_eval(a == 10); // it will produce two results: TRUE and FALSE
> }
> clang_analyzer_eval(a == 10); // it will produce three results: TRUE, FALSE, 
> and FALSE
> ```
> 
> We don't want to test how path splitting works in these particular tests 
> (they are about solver and constant folding after all), that's why we try to 
> have only one path going through each `clang_analyzer_eval(...)`
> 
> In this example, you still have residual paths where `c != INT_MIN`, `c == 
> INT_MIN and d != INT_MIN`, and `c == INT_MIN and d == INT_MIN`.
I should add tests for these paths as well so that these can be checked. For 
further cases, I will enforce single path evaluation in test cases (which will 
make it easier to handle here).


================
Comment at: clang/test/Analysis/constant-folding.c:304-305
+  if (c > 0 && d > 0) {
+    clang_analyzer_eval((c + d) > 1); // expected-warning{{TRUE}}
+    clang_analyzer_eval((c + d) < -1); // expected-warning{{TRUE}}
+  }
----------------
vsavchenko wrote:
> How can these two statements be TRUE at the same time?
Right, my bad. They both should be `UNKNOWN`.

As, `c` and `d` are signed 32-bit positive integers, hence their respective 
values will be in `[1, INT_MAX]`.

When `c == d == 1` then `c + d == 2`, and when `c == d == INT_MAX` then `c + d 
== -2` (overflow). Only possible values which `c + d` **cannot** attain are 
`{-1, 0, 1}`.

As a simple proof:

Dividing this range into 
  R1 = [1, INT_MAX/2] and R2 = [(INT_MAX/2) + 1, INT_MAX]

Now, `c + d` will have 4 combination of ranges to be solved:
- `R1 + R1` : this will never overflow as the maximum value it can attain will 
be `INT_MAX - 1` (when `c == d  == INT_MAX/2`)
- while in `R1 + R2`, `R2 + R1`, and `R2 + R2` expressions will overflow, 
leading value of `c + d` from `INT_MIN` to `-2`, except for case `INT_MAX/2 + 
(INT_MAX/2 + 1)`, where `c + d == INT_MAX`.

Hence, only possible values which can never be attained by `c + d` will be 
`{-1, 0, 1}`. So, the range for our purposes will be `[INT_MIN, -2] U [2, 
INT_MAX]`.

I think I should write tests for `c + d != {-1, 0, 1}` which will make more 
sense here.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D103440

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to