1 // RUN: %clang_analyze_cc1 -analyzer-checker=debug.ExprInspection,core.builtin -analyzer-config aggressive-binary-operation-simplification=true -verify %s 2 3 void clang_analyzer_eval(int); 4 5 void exit(int); 6 7 #define UINT_MIN (0U) 8 #define UINT_MAX (~UINT_MIN) 9 #define UINT_MID (UINT_MAX / 2 + 1) 10 #define INT_MAX (UINT_MAX & (UINT_MAX >> 1)) 11 #define INT_MIN (UINT_MAX & ~(UINT_MAX >> 1)) 12 13 extern void __assert_fail (__const char *__assertion, __const char *__file, 14 unsigned int __line, __const char *__function) 15 __attribute__ ((__noreturn__)); 16 #define assert(expr) \ 17 ((expr) ? (void)(0) : __assert_fail (#expr, __FILE__, __LINE__, __func__)) 18 19 void assert_in_range(int x) { 20 assert(x <= ((int)INT_MAX / 4)); 21 assert(x >= -(((int)INT_MAX) / 4)); 22 } 23 24 void assert_in_wide_range(int x) { 25 assert(x <= ((int)INT_MAX / 2)); 26 assert(x >= -(((int)INT_MAX) / 2)); 27 } 28 29 void assert_in_range_2(int m, int n) { 30 assert_in_range(m); 31 assert_in_range(n); 32 } 33 34 void equal(int m, int n) { 35 assert_in_range_2(m, n); 36 if (m != n) 37 return; 38 assert_in_wide_range(m - n); 39 clang_analyzer_eval(n == m); // expected-warning{{TRUE}} 40 } 41 42 void non_equal(int m, int n) { 43 assert_in_range_2(m, n); 44 if (m == n) 45 return; 46 assert_in_wide_range(m - n); 47 clang_analyzer_eval(n != m); // expected-warning{{TRUE}} 48 } 49 50 void less_or_equal(int m, int n) { 51 assert_in_range_2(m, n); 52 if (m < n) 53 return; 54 assert_in_wide_range(m - n); 55 clang_analyzer_eval(n <= m); // expected-warning{{TRUE}} 56 } 57 58 void less(int m, int n) { 59 assert_in_range_2(m, n); 60 if (m <= n) 61 return; 62 assert_in_wide_range(m - n); 63 clang_analyzer_eval(n < m); // expected-warning{{TRUE}} 64 } 65 66 void greater_or_equal(int m, int n) { 67 assert_in_range_2(m, n); 68 if (m > n) 69 return; 70 assert_in_wide_range(m - n); 71 clang_analyzer_eval(n >= m); // expected-warning{{TRUE}} 72 } 73 74 void greater(int m, int n) { 75 assert_in_range_2(m, n); 76 if (m >= n) 77 return; 78 assert_in_wide_range(m - n); 79 clang_analyzer_eval(n > m); // expected-warning{{TRUE}} 80 } 81 82 void negate_positive_range(int m, int n) { 83 if (m - n <= 0) 84 return; 85 clang_analyzer_eval(n - m < 0); // expected-warning{{TRUE}} 86 clang_analyzer_eval(n - m > INT_MIN); // expected-warning{{TRUE}} 87 clang_analyzer_eval(n - m == INT_MIN); // expected-warning{{FALSE}} 88 } 89 90 void negate_int_min(int m, int n) { 91 if (m - n != INT_MIN) 92 return; 93 clang_analyzer_eval(n - m == INT_MIN); // expected-warning{{TRUE}} 94 } 95 96 void negate_mixed(int m, int n) { 97 if (m -n > INT_MIN && m - n <= 0) 98 return; 99 clang_analyzer_eval(n - m <= 0); // expected-warning{{TRUE}} 100 } 101 102 void effective_range(int m, int n) { 103 assert(m - n >= 0); 104 assert(n - m >= 0); 105 clang_analyzer_eval(m - n == 0); // expected-warning{{TRUE}} 106 clang_analyzer_eval(n - m == 0); // expected-warning{{TRUE}} 107 } 108 109 void effective_range_2(int m, int n) { 110 assert(m - n <= 0); 111 assert(n - m <= 0); 112 clang_analyzer_eval(m - n == 0); // expected-warning{{TRUE}} expected-warning{{FALSE}} 113 clang_analyzer_eval(n - m == 0); // expected-warning{{TRUE}} expected-warning{{FALSE}} 114 } 115 116 void negate_unsigned_min(unsigned m, unsigned n) { 117 if (m - n == UINT_MIN) { 118 clang_analyzer_eval(n - m == UINT_MIN); // expected-warning{{TRUE}} 119 clang_analyzer_eval(n - m != UINT_MIN); // expected-warning{{FALSE}} 120 clang_analyzer_eval(n - m > UINT_MIN); // expected-warning{{FALSE}} 121 clang_analyzer_eval(n - m < UINT_MIN); // expected-warning{{FALSE}} 122 } 123 } 124 125 void negate_unsigned_mid(unsigned m, unsigned n) { 126 if (m - n == UINT_MID) { 127 clang_analyzer_eval(n - m == UINT_MID); // expected-warning{{TRUE}} 128 clang_analyzer_eval(n - m != UINT_MID); // expected-warning{{FALSE}} 129 } 130 } 131 132 void negate_unsigned_mid2(unsigned m, unsigned n) { 133 if (m - n < UINT_MID && m - n > UINT_MIN) { 134 clang_analyzer_eval(n - m > UINT_MID); // expected-warning{{TRUE}} 135 clang_analyzer_eval(n - m < UINT_MID); // expected-warning{{FALSE}} 136 } 137 } 138 139 void negate_unsigned_max(unsigned m, unsigned n) { 140 if (m - n == UINT_MAX) { 141 clang_analyzer_eval(n - m == 1); // expected-warning{{TRUE}} 142 clang_analyzer_eval(n - m != 1); // expected-warning{{FALSE}} 143 } 144 } 145 146 void negate_unsigned_one(unsigned m, unsigned n) { 147 if (m - n == 1) { 148 clang_analyzer_eval(n - m == UINT_MAX); // expected-warning{{TRUE}} 149 clang_analyzer_eval(n - m < UINT_MAX); // expected-warning{{FALSE}} 150 } 151 } 152 153 // The next code is a repro for the bug PR41588 154 void negated_unsigned_range(unsigned x, unsigned y) { 155 clang_analyzer_eval(x - y != 0); // expected-warning{{FALSE}} expected-warning{{TRUE}} 156 clang_analyzer_eval(y - x != 0); // expected-warning{{FALSE}} expected-warning{{TRUE}} 157 // expected no assertion on the next line 158 clang_analyzer_eval(x - y != 0); // expected-warning{{FALSE}} expected-warning{{TRUE}} 159 } 160