1 // RUN: %clang_analyze_cc1 -triple x86_64-unknown-unknown -verify %s \ 2 // RUN: -analyzer-checker=core,debug.ExprInspection,alpha.core.BoolAssignment 3 4 #define __UINT_MAX__ (__INT_MAX__ * 2U + 1U) 5 #define __INT_MIN__ (-__INT_MAX__ - 1) 6 7 void clang_analyzer_dump_int(int); 8 void clang_analyzer_dump_long(long); 9 void clang_analyzer_eval(int); 10 void clang_analyzer_warnIfReached(void); 11 12 void test_add_nooverflow(void) 13 { 14 int res; 15 16 if (__builtin_add_overflow(10, 20, &res)) { 17 clang_analyzer_warnIfReached(); 18 return; 19 } 20 21 clang_analyzer_dump_int(res); //expected-warning{{30 S32b}} 22 } 23 24 void test_add_overflow(void) 25 { 26 int res; 27 28 if (__builtin_add_overflow(__INT_MAX__, 1, &res)) { 29 clang_analyzer_dump_int(res); //expected-warning{{1st function call argument is an uninitialized value}} 30 return; 31 } 32 33 clang_analyzer_warnIfReached(); 34 } 35 36 void test_add_underoverflow(void) 37 { 38 int res; 39 40 if (__builtin_add_overflow(__INT_MIN__, -1, &res)) { 41 clang_analyzer_dump_int(res); //expected-warning{{1st function call argument is an uninitialized value}} 42 return; 43 } 44 45 clang_analyzer_warnIfReached(); 46 } 47 48 void test_sub_underflow(void) 49 { 50 int res; 51 52 if (__builtin_sub_overflow(__INT_MIN__, 10, &res)) { 53 return; 54 } 55 56 clang_analyzer_warnIfReached(); 57 } 58 59 void test_sub_overflow(void) 60 { 61 int res; 62 63 if (__builtin_sub_overflow(__INT_MAX__, -1, &res)) { 64 return; 65 } 66 67 clang_analyzer_warnIfReached(); 68 } 69 70 void test_sub_nooverflow(void) 71 { 72 int res; 73 74 if (__builtin_sub_overflow(__INT_MAX__, 1, &res)) { 75 clang_analyzer_warnIfReached(); 76 return; 77 } 78 79 clang_analyzer_dump_int(res); //expected-warning{{2147483646 S32b}} 80 } 81 82 void test_mul_overflow(void) 83 { 84 int res; 85 86 if (__builtin_mul_overflow(__INT_MAX__, 2, &res)) { 87 return; 88 } 89 90 clang_analyzer_warnIfReached(); 91 } 92 93 void test_mul_underflow(void) 94 { 95 int res; 96 97 if (__builtin_mul_overflow(__INT_MIN__, -2, &res)) { 98 return; 99 } 100 101 clang_analyzer_warnIfReached(); 102 } 103 104 void test_mul_nooverflow(void) 105 { 106 int res; 107 108 if (__builtin_mul_overflow(10, -2, &res)) { 109 clang_analyzer_warnIfReached(); 110 return; 111 } 112 113 clang_analyzer_dump_int(res); //expected-warning{{-20 S32b}} 114 } 115 116 void test_nooverflow_diff_types(void) 117 { 118 long res; 119 120 // This is not an overflow, since result type is long. 121 if (__builtin_add_overflow(__INT_MAX__, 1, &res)) { 122 clang_analyzer_warnIfReached(); 123 return; 124 } 125 126 clang_analyzer_dump_long(res); //expected-warning{{2147483648 S64b}} 127 } 128 129 void test_uaddll_overflow_contraints(unsigned long a, unsigned long b) 130 { 131 unsigned long long res; 132 133 if (a != 10) 134 return; 135 if (b != 10) 136 return; 137 138 if (__builtin_uaddll_overflow(a, b, &res)) { 139 clang_analyzer_warnIfReached(); 140 return; 141 } 142 } 143 144 void test_uadd_overflow_contraints(unsigned a, unsigned b) 145 { 146 unsigned res; 147 148 if (a > 5) 149 return; 150 if (b != 10) 151 return; 152 153 if (__builtin_uadd_overflow(a, b, &res)) { 154 clang_analyzer_warnIfReached(); 155 return; 156 } 157 } 158 159 void test_bool_assign(void) 160 { 161 int res; 162 163 // Reproduce issue from GH#111147. __builtin_*_overflow funcions 164 // should return _Bool, but not int. 165 _Bool ret = __builtin_mul_overflow(10, 20, &res); // no crash 166 } 167