389 lines · c
1// RUN: %clang_analyze_cc1 -verify %s \2// RUN: -analyzer-checker=core,debug.ExprInspection \3// RUN: -analyzer-config eagerly-assume=false4 5#define NULL (void *)06 7#define UCHAR_MAX (unsigned char)(~0U)8#define CHAR_MAX (char)(UCHAR_MAX & (UCHAR_MAX >> 1))9#define CHAR_MIN (char)(UCHAR_MAX & ~(UCHAR_MAX >> 1))10 11void clang_analyzer_value(int);12void clang_analyzer_eval(int);13void clang_analyzer_warnIfReached(void);14 15int getInt(void);16 17void zeroImpliesEquality(int a, int b) {18 clang_analyzer_eval((a - b) == 0); // expected-warning{{UNKNOWN}}19 if ((a - b) == 0) {20 clang_analyzer_eval(b != a); // expected-warning{{FALSE}}21 clang_analyzer_eval(b == a); // expected-warning{{TRUE}}22 clang_analyzer_eval(!(a != b)); // expected-warning{{TRUE}}23 clang_analyzer_eval(!(b == a)); // expected-warning{{FALSE}}24 return;25 }26 clang_analyzer_eval((a - b) == 0); // expected-warning{{FALSE}}27 clang_analyzer_eval(b == a); // expected-warning{{FALSE}}28 clang_analyzer_eval(b != a); // expected-warning{{TRUE}}29}30 31typedef int I32_A;32typedef int I32_B;33void zeroImpliesEqualityWithTypedef(I32_A a, I32_B b) {34 clang_analyzer_eval((a - b) == 0); // expected-warning{{UNKNOWN}}35 if ((a - b) == 0) {36 clang_analyzer_eval(b != a); // expected-warning{{FALSE}}37 clang_analyzer_eval(b == a); // expected-warning{{TRUE}}38 clang_analyzer_eval(!(a != b)); // expected-warning{{TRUE}}39 clang_analyzer_eval(!(b == a)); // expected-warning{{FALSE}}40 return;41 }42 clang_analyzer_eval((a - b) == 0); // expected-warning{{FALSE}}43 clang_analyzer_eval(b == a); // expected-warning{{FALSE}}44 clang_analyzer_eval(b != a); // expected-warning{{TRUE}}45}46 47void zeroImpliesReversedEqual(int a, int b) {48 clang_analyzer_eval((b - a) == 0); // expected-warning{{UNKNOWN}}49 if ((b - a) == 0) {50 clang_analyzer_eval(b != a); // expected-warning{{FALSE}}51 clang_analyzer_eval(b == a); // expected-warning{{TRUE}}52 return;53 }54 clang_analyzer_eval((b - a) == 0); // expected-warning{{FALSE}}55 clang_analyzer_eval(b == a); // expected-warning{{FALSE}}56 clang_analyzer_eval(b != a); // expected-warning{{TRUE}}57}58 59void canonicalEqual(int a, int b) {60 clang_analyzer_eval(a == b); // expected-warning{{UNKNOWN}}61 if (a == b) {62 clang_analyzer_eval(b == a); // expected-warning{{TRUE}}63 return;64 }65 clang_analyzer_eval(a == b); // expected-warning{{FALSE}}66 clang_analyzer_eval(b == a); // expected-warning{{FALSE}}67}68 69void test(int a, int b, int c, int d) {70 if (a == b && c == d) {71 if (a == 0 && b == d) {72 clang_analyzer_eval(c == 0); // expected-warning{{TRUE}}73 }74 c = 10;75 if (b == d) {76 clang_analyzer_eval(c == 10); // expected-warning{{TRUE}}77 clang_analyzer_eval(d == 10); // expected-warning{{UNKNOWN}}78 // expected-warning@-1{{FALSE}}79 clang_analyzer_eval(b == a); // expected-warning{{TRUE}}80 clang_analyzer_eval(a == d); // expected-warning{{TRUE}}81 82 b = getInt();83 clang_analyzer_eval(a == d); // expected-warning{{TRUE}}84 clang_analyzer_eval(a == b); // expected-warning{{UNKNOWN}}85 }86 }87 88 if (a != b && b == c) {89 if (c == 42) {90 clang_analyzer_eval(b == 42); // expected-warning{{TRUE}}91 clang_analyzer_eval(a != 42); // expected-warning{{TRUE}}92 }93 }94}95 96void testIntersection(int a, int b, int c) {97 if (a < 42 && b > 15 && c >= 25 && c <= 30) {98 if (a != b)99 return;100 101 clang_analyzer_eval(a > 15); // expected-warning{{TRUE}}102 clang_analyzer_eval(b < 42); // expected-warning{{TRUE}}103 clang_analyzer_eval(a <= 30); // expected-warning{{UNKNOWN}}104 105 if (c == b) {106 // For all equal symbols, we should track the minimal common range.107 //108 // Also, it should be noted that c is dead at this point, but the109 // constraint initially associated with c is still around.110 clang_analyzer_eval(a >= 25 && a <= 30); // expected-warning{{TRUE}}111 clang_analyzer_eval(b >= 25 && b <= 30); // expected-warning{{TRUE}}112 }113 }114}115 116void testPromotion(int a, char b) {117 if (b > 10) {118 if (a == b) {119 // FIXME: support transferring char ranges onto equal int symbols120 // when char is promoted to int121 clang_analyzer_eval(a > 10); // expected-warning{{UNKNOWN}}122 clang_analyzer_eval(a <= CHAR_MAX); // expected-warning{{UNKNOWN}}123 }124 }125}126 127void testPromotionOnlyTypes(int a, char b) {128 if (a == b) {129 // FIXME: support transferring char ranges onto equal int symbols130 // when char is promoted to int131 clang_analyzer_eval(a <= CHAR_MAX); // expected-warning{{UNKNOWN}}132 }133}134 135void testDowncast(int a, unsigned char b) {136 if (a <= -10) {137 if ((unsigned char)a == b) {138 // Even though ranges for a and b do not intersect,139 // ranges for (unsigned char)a and b do.140 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}141 }142 if (a == b) {143 // FIXME: This case on the other hand is different, it shouldn't be144 // reachable. However, the corrent symbolic information available145 // to the solver doesn't allow it to distinguish this expression146 // from the previous one.147 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}148 }149 }150}151 152void testPointers(int *a, int *b, int *c, int *d) {153 if (a == b && c == d) {154 if (a == NULL && b == d) {155 clang_analyzer_eval(c == NULL); // expected-warning{{TRUE}}156 }157 }158 159 if (a != b && b == c) {160 if (c == NULL) {161 clang_analyzer_eval(a != NULL); // expected-warning{{TRUE}}162 }163 }164}165 166void testDisequalitiesAfter(int a, int b, int c) {167 if (a >= 10 && b <= 42) {168 if (a == b && c == 15 && c != a) {169 clang_analyzer_eval(b != c); // expected-warning{{TRUE}}170 clang_analyzer_eval(a != 15); // expected-warning{{TRUE}}171 clang_analyzer_eval(b != 15); // expected-warning{{TRUE}}172 clang_analyzer_eval(b >= 10); // expected-warning{{TRUE}}173 clang_analyzer_eval(a <= 42); // expected-warning{{TRUE}}174 }175 }176}177 178void testDisequalitiesBefore(int a, int b, int c) {179 if (a >= 10 && b <= 42 && c == 15) {180 if (a == b && c != a) {181 clang_analyzer_eval(b != c); // expected-warning{{TRUE}}182 clang_analyzer_eval(a != 15); // expected-warning{{TRUE}}183 clang_analyzer_eval(b != 15); // expected-warning{{TRUE}}184 clang_analyzer_eval(b >= 10); // expected-warning{{TRUE}}185 clang_analyzer_eval(a <= 42); // expected-warning{{TRUE}}186 }187 }188}189 190void avoidInfeasibleConstraintsForClasses(int a, int b) {191 if (a >= 0 && a <= 10 && b >= 20 && b <= 50) {192 if ((b - a) == 0) {193 clang_analyzer_warnIfReached(); // no warning194 }195 if (a == b) {196 clang_analyzer_warnIfReached(); // no warning197 }198 if (a != b) {199 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}200 } else {201 clang_analyzer_warnIfReached(); // no warning202 }203 }204}205 206void avoidInfeasibleConstraintforGT(int a, int b) {207 int c = b - a;208 if (c <= 0)209 return;210 // c > 0211 // b - a > 0212 // b > a213 if (a != b) {214 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}215 return;216 }217 clang_analyzer_warnIfReached(); // no warning218 // a == b219 if (c < 0)220 ;221}222 223void avoidInfeasibleConstraintforLT(int a, int b) {224 int c = b - a;225 if (c >= 0)226 return;227 // c < 0228 // b - a < 0229 // b < a230 if (a != b) {231 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}232 return;233 }234 clang_analyzer_warnIfReached(); // no warning235 // a == b236 if (c < 0)237 ;238}239 240void implyDisequalityFromGT(int a, int b) {241 if (a > b) {242 clang_analyzer_eval(a == b); // expected-warning{{FALSE}}243 clang_analyzer_eval(a != b); // expected-warning{{TRUE}}244 }245}246 247void implyDisequalityFromLT(int a, int b) {248 if (a < b) {249 clang_analyzer_eval(a == b); // expected-warning{{FALSE}}250 clang_analyzer_eval(a != b); // expected-warning{{TRUE}}251 }252}253 254void deletePointBefore(int x, int tmp) {255 if(tmp == 0)256 if(x != tmp)257 clang_analyzer_value(x); // expected-warning {{32s:{ [-2147483648, -1], [1, 2147483647] }}}258}259 260void deletePointAfter(int x, int tmp) {261 if(x != tmp)262 if(tmp == 2147483647)263 clang_analyzer_value(x); // expected-warning {{32s:{ [-2147483648, 2147483646] }}}264}265 266void deleteTwoPoints(int x, int tmp1, int tmp2) {267 if(x != tmp1) {268 if (tmp1 == 42 && tmp2 == 87) {269 clang_analyzer_value(x); // expected-warning {{32s:{ [-2147483648, 41], [43, 2147483647] }}}270 if(x != tmp2)271 clang_analyzer_value(x); // expected-warning {{32s:{ [-2147483648, 41], [43, 86], [88, 2147483647] }}}272 }273 }274}275 276void deleteAllPoints(unsigned char x, unsigned char *arr) {277 278#define cond(n) \279arr[n##0] == n##0 && \280arr[n##1] == n##1 && \281arr[n##2] == n##2 && \282arr[n##3] == n##3 && \283arr[n##4] == n##4 && \284arr[n##5] == n##5 && \285arr[n##6] == n##6 && \286arr[n##7] == n##7 && \287arr[n##8] == n##8 && \288arr[n##9] == n##9 && \289 290#define condX(n) \291arr[n##0] != x && \292arr[n##1] != x && \293arr[n##2] != x && \294arr[n##3] != x && \295arr[n##4] != x && \296arr[n##5] != x && \297arr[n##6] != x && \298arr[n##7] != x && \299arr[n##8] != x && \300arr[n##9] != x && \301 302 clang_analyzer_value(x); // expected-warning {{{ [0, 255] }}}303 if (304 cond() // 0 .. 9305 cond(1) // 10 .. 19306 cond(2) // 20 .. 29307 cond(3) // 30 .. 39308 cond(4) // 40 .. 49309 cond(5) // 50 .. 59310 cond(6) // 60 .. 69311 cond(7) // 70 .. 79312 cond(8) // 80 .. 89313 cond(9) // 90 .. 99314 cond(10) // 100 .. 209315 cond(11) // 110 .. 219316 cond(12) // 120 .. 229317 cond(13) // 130 .. 239318 cond(14) // 140 .. 249319 cond(15) // 150 .. 259320 cond(16) // 160 .. 269321 cond(17) // 170 .. 279322 cond(18) // 180 .. 289323 cond(19) // 190 .. 199324 cond(20) // 200 .. 209325 cond(21) // 210 .. 219326 cond(22) // 220 .. 229327 cond(23) // 230 .. 239328 cond(24) // 240 .. 249329 arr[250] == 250 &&330 arr[251] == 251 &&331 arr[252] == 252 &&332 arr[253] == 253 &&333 arr[254] == 254 &&334 arr[255] == 255335 ) {336 if (337 condX() // 0 .. 9338 condX(1) // 10 .. 19339 condX(2) // 20 .. 29340 condX(3) // 30 .. 39341 condX(4) // 40 .. 49342 condX(5) // 50 .. 59343 condX(6) // 60 .. 69344 condX(7) // 70 .. 79345 condX(8) // 80 .. 89346 condX(9) // 90 .. 99347 condX(10) // 100 .. 209348 condX(11) // 110 .. 219349 condX(12) // 120 .. 229350 condX(13) // 130 .. 239351 condX(14) // 140 .. 249352 condX(15) // 150 .. 259353 condX(16) // 160 .. 269354 condX(17) // 170 .. 279355 condX(18) // 180 .. 289356 condX(19) // 190 .. 199357 condX(20) // 200 .. 209358 condX(21) // 210 .. 219359 condX(22) // 220 .. 229360 condX(23) // 230 .. 239361 arr[240] != x &&362 arr[241] != x &&363 arr[242] != x &&364 arr[243] != x &&365 arr[244] != x &&366 arr[245] != x &&367 arr[246] != x &&368 arr[247] != x &&369 arr[248] != x &&370 arr[249] != x371 ) {372 clang_analyzer_value(x); // expected-warning {{{ [250, 255] }}}373 if (374 arr[250] != x &&375 arr[251] != x &&376 //skip arr[252]377 arr[253] != x &&378 arr[254] != x &&379 arr[255] != x380 ) {381 clang_analyzer_value(x); // expected-warning {{32s:252}}382 if (arr[252] != x) {383 clang_analyzer_warnIfReached(); // unreachable384 }385 }386 }387 }388}389