380 lines · c
1// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.FixedAddr,alpha.core.PointerArithm,debug.ExprInspection -Wno-pointer-to-int-cast -verify -triple x86_64-apple-darwin9 -Wno-tautological-pointer-compare -analyzer-config eagerly-assume=false %s2// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.FixedAddr,alpha.core.PointerArithm,debug.ExprInspection -Wno-pointer-to-int-cast -verify -triple i686-apple-darwin9 -Wno-tautological-pointer-compare -analyzer-config eagerly-assume=false %s3 4#include "Inputs/system-header-simulator.h"5 6void clang_analyzer_eval(int);7void clang_analyzer_dump(int);8 9void f1(void) {10 int a[10];11 int *p = a;12 ++p;13}14 15char* foo(void);16 17void f2(void) {18 char *p = foo();19 ++p;20}21 22// This test case checks if we get the right rvalue type of a TypedViewRegion.23// The ElementRegion's type depends on the array region's rvalue type. If it was24// a pointer type, we would get a loc::SymbolVal for '*p'.25void* memchr(const void *, int, __typeof__(sizeof(0)));26static int27domain_port (const char *domain_b, const char *domain_e,28 const char **domain_e_ptr)29{30 int port = 0;31 32 const char *p;33 const char *colon = memchr (domain_b, ':', domain_e - domain_b);34 35 for (p = colon + 1; p < domain_e ; p++)36 port = 10 * port + (*p - '0');37 return port;38}39 40#define FIXED_VALUE (int*) 0x111141 42void f4(void) {43 int *p;44 p = (int*) 0x10000; // expected-warning{{Using a fixed address is not portable because that address will probably not be valid in all environments or platforms}}45 46 int *p1;47 p1 = p; // no warning48 49 long x = 0x10100;50 x += 10;51 p = (int*) x; // expected-warning{{Using a fixed address is not portable because that address will probably not be valid in all environments or platforms}}52 53 struct sigaction sa;54 sa.sa_handler = SIG_IGN; // no warning (exclude macros defined in system header)55 sigaction(SIGINT, &sa, NULL);56 57 p = FIXED_VALUE; // expected-warning{{Using a fixed address is not portable because that address will probably not be valid in all environments or platforms}}58}59 60void f5(void) {61 int x, y;62 int *p;63 p = &x + 1; // expected-warning{{Pointer arithmetic on non-array variables relies on memory layout, which is dangerous}}64 65 int a[10];66 p = a + 1; // no-warning67}68 69// Allow arithmetic on different symbolic regions.70void f6(int *p, int *q) {71 int d = q - p; // no-warning72}73 74void null_operand(int *a) {75start:76 // LHS is a label, RHS is NULL77 clang_analyzer_eval(&&start != 0); // expected-warning{{TRUE}}78 clang_analyzer_eval(&&start >= 0); // expected-warning{{TRUE}}79 clang_analyzer_eval(&&start > 0); // expected-warning{{TRUE}}80 clang_analyzer_eval((&&start - 0) != 0); // expected-warning{{TRUE}}81 82 // LHS is a non-symbolic value, RHS is NULL83 clang_analyzer_eval(&a != 0); // expected-warning{{TRUE}}84 clang_analyzer_eval(&a >= 0); // expected-warning{{TRUE}}85 clang_analyzer_eval(&a > 0); // expected-warning{{TRUE}}86 clang_analyzer_eval((&a - 0) != 0); // expected-warning{{TRUE}}87 88 // LHS is NULL, RHS is non-symbolic89 // The same code is used for labels and non-symbolic values.90 clang_analyzer_eval(0 != &a); // expected-warning{{TRUE}}91 clang_analyzer_eval(0 <= &a); // expected-warning{{TRUE}}92 clang_analyzer_eval(0 < &a); // expected-warning{{TRUE}}93 94 // LHS is a symbolic value, RHS is NULL95 clang_analyzer_eval(a != 0); // expected-warning{{UNKNOWN}}96 clang_analyzer_eval(a >= 0); // expected-warning{{TRUE}}97 clang_analyzer_eval(a <= 0); // expected-warning{{UNKNOWN}}98 clang_analyzer_eval((a - 0) != 0); // expected-warning{{UNKNOWN}}99 100 // LHS is NULL, RHS is a symbolic value101 clang_analyzer_eval(0 != a); // expected-warning{{UNKNOWN}}102 clang_analyzer_eval(0 <= a); // expected-warning{{TRUE}}103 clang_analyzer_eval(0 < a); // expected-warning{{UNKNOWN}}104}105 106void const_locs(void) {107 char *a = (char*)0x1000;108 char *b = (char*)0x1100;109start:110 clang_analyzer_eval(a != b); // expected-warning{{TRUE}}111 clang_analyzer_eval(a < b); // expected-warning{{TRUE}}112 clang_analyzer_eval(a <= b); // expected-warning{{TRUE}}113 clang_analyzer_eval((b-a) == 0x100); // expected-warning{{TRUE}}114 115 clang_analyzer_eval(&&start == a); // expected-warning{{UNKNOWN}}116 clang_analyzer_eval(a == &&start); // expected-warning{{UNKNOWN}}117 clang_analyzer_eval(&a == (char**)a); // expected-warning{{UNKNOWN}}118 clang_analyzer_eval((char**)a == &a); // expected-warning{{UNKNOWN}}119}120 121void array_matching_types(void) {122 int array[10];123 int *a = &array[2];124 int *b = &array[5];125 126 clang_analyzer_eval(a != b); // expected-warning{{TRUE}}127 clang_analyzer_eval(a < b); // expected-warning{{TRUE}}128 clang_analyzer_eval(a <= b); // expected-warning{{TRUE}}129 clang_analyzer_eval((b-a) != 0); // expected-warning{{TRUE}}130}131 132// This takes a different code path than array_matching_types()133void array_different_types(void) {134 int array[10];135 int *a = &array[2];136 char *b = (char*)&array[5];137 138 clang_analyzer_eval(a != b); // expected-warning{{TRUE}} expected-warning{{comparison of distinct pointer types}}139 clang_analyzer_eval(a < b); // expected-warning{{TRUE}} expected-warning{{comparison of distinct pointer types}}140 clang_analyzer_eval(a <= b); // expected-warning{{TRUE}} expected-warning{{comparison of distinct pointer types}}141}142 143struct test { int x; int y; };144void struct_fields(void) {145 struct test a, b;146 147 clang_analyzer_eval(&a.x != &a.y); // expected-warning{{TRUE}}148 clang_analyzer_eval(&a.x < &a.y); // expected-warning{{TRUE}}149 clang_analyzer_eval(&a.x <= &a.y); // expected-warning{{TRUE}}150 151 clang_analyzer_eval(&a.x != &b.x); // expected-warning{{TRUE}}152 clang_analyzer_eval(&a.x > &b.x); // expected-warning{{UNKNOWN}}153 clang_analyzer_eval(&a.x >= &b.x); // expected-warning{{UNKNOWN}}154}155 156void mixed_region_types(void) {157 struct test s;158 int array[2];159 void *a = &array, *b = &s;160 161 clang_analyzer_eval(&a != &b); // expected-warning{{TRUE}}162 clang_analyzer_eval(&a > &b); // expected-warning{{UNKNOWN}}163 clang_analyzer_eval(&a >= &b); // expected-warning{{UNKNOWN}}164}165 166void symbolic_region(int *p) {167 int a;168 169 clang_analyzer_eval(&a != p); // expected-warning{{TRUE}}170 clang_analyzer_eval(&a > p); // expected-warning{{UNKNOWN}}171 clang_analyzer_eval(&a >= p); // expected-warning{{UNKNOWN}}172}173 174void PR7527 (int *p) {175 if (((int) p) & 1) // not crash176 return;177}178 179void use_symbols(int *lhs, int *rhs) {180 clang_analyzer_eval(lhs < rhs); // expected-warning{{UNKNOWN}}181 if (lhs < rhs)182 return;183 clang_analyzer_eval(lhs < rhs); // expected-warning{{FALSE}}184 185 clang_analyzer_eval(lhs - rhs); // expected-warning{{UNKNOWN}}186 if ((lhs - rhs) != 5)187 return;188 clang_analyzer_eval((lhs - rhs) == 5); // expected-warning{{TRUE}}189}190 191void equal_implies_zero(int *lhs, int *rhs) {192 clang_analyzer_eval(lhs == rhs); // expected-warning{{UNKNOWN}}193 if (lhs == rhs) {194 clang_analyzer_eval(lhs != rhs); // expected-warning{{FALSE}}195 clang_analyzer_eval((rhs - lhs) == 0); // expected-warning{{TRUE}}196 return;197 }198 clang_analyzer_eval(lhs == rhs); // expected-warning{{FALSE}}199 clang_analyzer_eval(lhs != rhs); // expected-warning{{TRUE}}200 clang_analyzer_eval((rhs - lhs) == 0); // expected-warning{{FALSE}}201}202 203void zero_implies_equal(int *lhs, int *rhs) {204 clang_analyzer_eval((rhs - lhs) == 0); // expected-warning{{UNKNOWN}}205 if ((rhs - lhs) == 0) {206 clang_analyzer_eval(lhs != rhs); // expected-warning{{FALSE}}207 clang_analyzer_eval(lhs == rhs); // expected-warning{{TRUE}}208 return;209 }210 clang_analyzer_eval((rhs - lhs) == 0); // expected-warning{{FALSE}}211 clang_analyzer_eval(lhs == rhs); // expected-warning{{FALSE}}212 clang_analyzer_eval(lhs != rhs); // expected-warning{{TRUE}}213}214 215void comparisons_imply_size(int *lhs, int *rhs) {216 clang_analyzer_eval(lhs <= rhs); // expected-warning{{UNKNOWN}}217 218 if (lhs > rhs) {219 clang_analyzer_eval((rhs - lhs) == 0); // expected-warning{{FALSE}}220 return;221 }222 223 clang_analyzer_eval(lhs <= rhs); // expected-warning{{TRUE}}224 clang_analyzer_eval((rhs - lhs) >= 0); // expected-warning{{TRUE}}225 clang_analyzer_eval((rhs - lhs) > 0); // expected-warning{{UNKNOWN}}226 227 if (lhs >= rhs) {228 clang_analyzer_eval((rhs - lhs) == 0); // expected-warning{{TRUE}}229 return;230 }231 232 clang_analyzer_eval(lhs == rhs); // expected-warning{{FALSE}}233 clang_analyzer_eval(lhs < rhs); // expected-warning{{TRUE}}234 clang_analyzer_eval((rhs - lhs) > 0); // expected-warning{{TRUE}}235}236 237void size_implies_comparison(int *lhs, int *rhs) {238 clang_analyzer_eval(lhs <= rhs); // expected-warning{{UNKNOWN}}239 240 if ((rhs - lhs) < 0) {241 clang_analyzer_eval(lhs == rhs); // expected-warning{{FALSE}}242 return;243 }244 245 clang_analyzer_eval(lhs <= rhs); // expected-warning{{TRUE}}246 clang_analyzer_eval((rhs - lhs) >= 0); // expected-warning{{TRUE}}247 clang_analyzer_eval((rhs - lhs) > 0); // expected-warning{{UNKNOWN}}248 249 if ((rhs - lhs) <= 0) {250 clang_analyzer_eval(lhs == rhs); // expected-warning{{TRUE}}251 return;252 }253 254 clang_analyzer_eval(lhs == rhs); // expected-warning{{FALSE}}255 clang_analyzer_eval(lhs < rhs); // expected-warning{{TRUE}}256 clang_analyzer_eval((rhs - lhs) > 0); // expected-warning{{TRUE}}257}258 259void zero_implies_reversed_equal(int *lhs, int *rhs) {260 clang_analyzer_eval((rhs - lhs) == 0); // expected-warning{{UNKNOWN}}261 if ((rhs - lhs) == 0) {262 clang_analyzer_eval(rhs != lhs); // expected-warning{{FALSE}}263 clang_analyzer_eval(rhs == lhs); // expected-warning{{TRUE}}264 return;265 }266 clang_analyzer_eval((rhs - lhs) == 0); // expected-warning{{FALSE}}267 clang_analyzer_eval(rhs == lhs); // expected-warning{{FALSE}}268 clang_analyzer_eval(rhs != lhs); // expected-warning{{TRUE}}269}270 271void canonical_equal(int *lhs, int *rhs) {272 clang_analyzer_eval(lhs == rhs); // expected-warning{{UNKNOWN}}273 if (lhs == rhs) {274 clang_analyzer_eval(rhs == lhs); // expected-warning{{TRUE}}275 return;276 }277 clang_analyzer_eval(lhs == rhs); // expected-warning{{FALSE}}278 clang_analyzer_eval(rhs == lhs); // expected-warning{{FALSE}}279}280 281void compare_element_region_and_base(int *p) {282 int *q = p - 1;283 clang_analyzer_eval(p == q); // expected-warning{{FALSE}}284}285 286struct Point {287 int x;288 int y;289};290void symbolicFieldRegion(struct Point *points, int i, int j) {291 clang_analyzer_eval(&points[i].x == &points[j].x);// expected-warning{{UNKNOWN}}292 clang_analyzer_eval(&points[i].x == &points[i].y);// expected-warning{{FALSE}}293 clang_analyzer_eval(&points[i].x < &points[i].y);// expected-warning{{TRUE}}294}295 296void negativeIndex(char *str) {297 *(str + 1) = 'a';298 clang_analyzer_eval(*(str + 1) == 'a'); // expected-warning{{TRUE}}299 clang_analyzer_eval(*(str - 1) == 'a'); // expected-warning{{UNKNOWN}}300 301 char *ptr1 = str - 1;302 clang_analyzer_eval(*ptr1 == 'a'); // expected-warning{{UNKNOWN}}303 304 char *ptr2 = str;305 ptr2 -= 1;306 clang_analyzer_eval(*ptr2 == 'a'); // expected-warning{{UNKNOWN}}307 308 char *ptr3 = str;309 --ptr3;310 clang_analyzer_eval(*ptr3 == 'a'); // expected-warning{{UNKNOWN}}311}312 313void test_no_crash_on_pointer_to_label(void) {314 char *a = &&label;315 a[0] = 0;316label:;317}318 319typedef __attribute__((__ext_vector_type__(2))) float simd_float2;320float test_nowarning_on_vector_deref(void) {321 simd_float2 x = {0, 1};322 return x[1]; // no-warning323}324 325struct s {326 int v;327};328 329// These three expressions should produce the same sym vals.330void struct_pointer_canon(struct s *ps) {331 struct s ss = *ps;332 clang_analyzer_dump((*ps).v);333 // expected-warning-re@-1{{reg_${{[[:digit:]]+}}<int Element{SymRegion{reg_${{[[:digit:]]+}}<struct s * ps>},0 S64b,struct s}.v>}}334 clang_analyzer_dump(ps[0].v);335 // expected-warning-re@-1{{reg_${{[[:digit:]]+}}<int Element{SymRegion{reg_${{[[:digit:]]+}}<struct s * ps>},0 S64b,struct s}.v>}}336 clang_analyzer_dump(ps->v);337 // expected-warning-re@-1{{reg_${{[[:digit:]]+}}<int Element{SymRegion{reg_${{[[:digit:]]+}}<struct s * ps>},0 S64b,struct s}.v>}}338 clang_analyzer_eval((*ps).v == ps[0].v); // expected-warning{{TRUE}}339 clang_analyzer_eval((*ps).v == ps->v); // expected-warning{{TRUE}}340 clang_analyzer_eval(ps[0].v == ps->v); // expected-warning{{TRUE}}341}342 343void struct_pointer_canon_bidim(struct s **ps) {344 struct s ss = **ps;345 clang_analyzer_eval(&(ps[0][0].v) == &((*ps)->v)); // expected-warning{{TRUE}}346}347 348typedef struct s T1;349typedef struct s T2;350void struct_pointer_canon_typedef(T1 *ps) {351 T2 ss = *ps;352 clang_analyzer_dump((*ps).v);353 // expected-warning-re@-1{{reg_${{[[:digit:]]+}}<int Element{SymRegion{reg_${{[[:digit:]]+}}<T1 * ps>},0 S64b,struct s}.v>}}354 clang_analyzer_dump(ps[0].v);355 // expected-warning-re@-1{{reg_${{[[:digit:]]+}}<int Element{SymRegion{reg_${{[[:digit:]]+}}<T1 * ps>},0 S64b,struct s}.v>}}356 clang_analyzer_dump(ps->v);357 // expected-warning-re@-1{{reg_${{[[:digit:]]+}}<int Element{SymRegion{reg_${{[[:digit:]]+}}<T1 * ps>},0 S64b,struct s}.v>}}358 clang_analyzer_eval((*ps).v == ps[0].v); // expected-warning{{TRUE}}359 clang_analyzer_eval((*ps).v == ps->v); // expected-warning{{TRUE}}360 clang_analyzer_eval(ps[0].v == ps->v); // expected-warning{{TRUE}}361}362 363void struct_pointer_canon_bidim_typedef(T1 **ps) {364 T2 ss = **ps;365 clang_analyzer_eval(&(ps[0][0].v) == &((*ps)->v)); // expected-warning{{TRUE}}366}367 368void struct_pointer_canon_const(const struct s *ps) {369 struct s ss = *ps;370 clang_analyzer_dump((*ps).v);371 // expected-warning-re@-1{{reg_${{[[:digit:]]+}}<int Element{SymRegion{reg_${{[[:digit:]]+}}<const struct s * ps>},0 S64b,struct s}.v>}}372 clang_analyzer_dump(ps[0].v);373 // expected-warning-re@-1{{reg_${{[[:digit:]]+}}<int Element{SymRegion{reg_${{[[:digit:]]+}}<const struct s * ps>},0 S64b,struct s}.v>}}374 clang_analyzer_dump(ps->v);375 // expected-warning-re@-1{{reg_${{[[:digit:]]+}}<int Element{SymRegion{reg_${{[[:digit:]]+}}<const struct s * ps>},0 S64b,struct s}.v>}}376 clang_analyzer_eval((*ps).v == ps[0].v); // expected-warning{{TRUE}}377 clang_analyzer_eval((*ps).v == ps->v); // expected-warning{{TRUE}}378 clang_analyzer_eval(ps[0].v == ps->v); // expected-warning{{TRUE}}379}380