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