Adam Balogh | dcde8ac | 2018-07-23 10:50:20 +0000 | [diff] [blame] | 1 | // RUN: %clang_analyze_cc1 -analyzer-checker=debug.ExprInspection,core.builtin -analyzer-config aggressive-binary-operation-simplification=true -verify %s |
Adam Balogh | 77660ee | 2018-06-28 07:35:23 +0000 | [diff] [blame] | 2 | |
| 3 | void clang_analyzer_eval(int); |
| 4 | |
| 5 | void exit(int); |
| 6 | |
| 7 | #define UINT_MAX (~0U) |
| 8 | #define INT_MAX (UINT_MAX & (UINT_MAX >> 1)) |
| 9 | #define INT_MIN (UINT_MAX & ~(UINT_MAX >> 1)) |
| 10 | |
| 11 | extern void __assert_fail (__const char *__assertion, __const char *__file, |
| 12 | unsigned int __line, __const char *__function) |
| 13 | __attribute__ ((__noreturn__)); |
| 14 | #define assert(expr) \ |
| 15 | ((expr) ? (void)(0) : __assert_fail (#expr, __FILE__, __LINE__, __func__)) |
| 16 | |
| 17 | void assert_in_range(int x) { |
| 18 | assert(x <= ((int)INT_MAX / 4)); |
| 19 | assert(x >= -(((int)INT_MAX) / 4)); |
| 20 | } |
| 21 | |
| 22 | void assert_in_wide_range(int x) { |
| 23 | assert(x <= ((int)INT_MAX / 2)); |
| 24 | assert(x >= -(((int)INT_MAX) / 2)); |
| 25 | } |
| 26 | |
| 27 | void assert_in_range_2(int m, int n) { |
| 28 | assert_in_range(m); |
| 29 | assert_in_range(n); |
| 30 | } |
| 31 | |
| 32 | void equal(int m, int n) { |
| 33 | assert_in_range_2(m, n); |
| 34 | if (m != n) |
| 35 | return; |
| 36 | assert_in_wide_range(m - n); |
| 37 | clang_analyzer_eval(n == m); // expected-warning{{TRUE}} |
| 38 | } |
| 39 | |
| 40 | void non_equal(int m, int n) { |
| 41 | assert_in_range_2(m, n); |
| 42 | if (m == n) |
| 43 | return; |
| 44 | assert_in_wide_range(m - n); |
| 45 | clang_analyzer_eval(n != m); // expected-warning{{TRUE}} |
| 46 | } |
| 47 | |
| 48 | void less_or_equal(int m, int n) { |
| 49 | assert_in_range_2(m, n); |
| 50 | if (m < n) |
| 51 | return; |
| 52 | assert_in_wide_range(m - n); |
| 53 | clang_analyzer_eval(n <= m); // expected-warning{{TRUE}} |
| 54 | } |
| 55 | |
| 56 | void less(int m, int n) { |
| 57 | assert_in_range_2(m, n); |
| 58 | if (m <= n) |
| 59 | return; |
| 60 | assert_in_wide_range(m - n); |
| 61 | clang_analyzer_eval(n < m); // expected-warning{{TRUE}} |
| 62 | } |
| 63 | |
| 64 | void greater_or_equal(int m, int n) { |
| 65 | assert_in_range_2(m, n); |
| 66 | if (m > n) |
| 67 | return; |
| 68 | assert_in_wide_range(m - n); |
| 69 | clang_analyzer_eval(n >= m); // expected-warning{{TRUE}} |
| 70 | } |
| 71 | |
| 72 | void greater(int m, int n) { |
| 73 | assert_in_range_2(m, n); |
| 74 | if (m >= n) |
| 75 | return; |
| 76 | assert_in_wide_range(m - n); |
| 77 | clang_analyzer_eval(n > m); // expected-warning{{TRUE}} |
| 78 | } |
| 79 | |
| 80 | void negate_positive_range(int m, int n) { |
| 81 | if (m - n <= 0) |
| 82 | return; |
| 83 | clang_analyzer_eval(n - m < 0); // expected-warning{{TRUE}} |
| 84 | clang_analyzer_eval(n - m > INT_MIN); // expected-warning{{TRUE}} |
| 85 | clang_analyzer_eval(n - m == INT_MIN); // expected-warning{{FALSE}} |
| 86 | } |
| 87 | |
| 88 | void negate_int_min(int m, int n) { |
| 89 | if (m - n != INT_MIN) |
| 90 | return; |
| 91 | clang_analyzer_eval(n - m == INT_MIN); // expected-warning{{TRUE}} |
| 92 | } |
| 93 | |
| 94 | void negate_mixed(int m, int n) { |
| 95 | if (m -n > INT_MIN && m - n <= 0) |
| 96 | return; |
| 97 | clang_analyzer_eval(n - m <= 0); // expected-warning{{TRUE}} |
| 98 | } |