| Argyrios Kyrtzidis | 23ade50 | 2011-02-15 22:55:20 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -analyze -analyzer-checker=core.experimental.FixedAddr -analyzer-checker=core.experimental.PointerArithm -analyzer-checker=core.experimental.PointerSub -analyzer-check-objc-mem -analyzer-store=region -verify -triple x86_64-apple-darwin9 %s | 
 | 2 | // RUN: %clang_cc1 -analyze -analyzer-checker=core.experimental.FixedAddr -analyzer-checker=core.experimental.PointerArithm -analyzer-checker=core.experimental.PointerSub -analyzer-check-objc-mem -analyzer-store=region -verify -triple i686-apple-darwin9 %s | 
| Zhongxing Xu | e184b1e | 2009-03-03 00:28:42 +0000 | [diff] [blame] | 3 |  | 
| Jordy Rose | eac4a00 | 2010-06-28 08:26:15 +0000 | [diff] [blame] | 4 | // Used to trigger warnings for unreachable paths. | 
 | 5 | #define WARN do { int a, b; int c = &b-&a; } while (0) | 
 | 6 |  | 
| Zhongxing Xu | e184b1e | 2009-03-03 00:28:42 +0000 | [diff] [blame] | 7 | void f1() { | 
 | 8 |   int a[10]; | 
 | 9 |   int *p = a; | 
 | 10 |   ++p; | 
 | 11 | } | 
| Zhongxing Xu | 2b1dc17 | 2009-03-11 07:43:49 +0000 | [diff] [blame] | 12 |  | 
 | 13 | char* foo(); | 
 | 14 |  | 
 | 15 | void f2() { | 
 | 16 |   char *p = foo(); | 
 | 17 |   ++p; | 
 | 18 | } | 
| Zhongxing Xu | 3c4b379 | 2009-03-11 09:15:38 +0000 | [diff] [blame] | 19 |  | 
| Zhongxing Xu | e8cba00 | 2009-03-12 01:55:38 +0000 | [diff] [blame] | 20 | // This test case checks if we get the right rvalue type of a TypedViewRegion. | 
 | 21 | // The ElementRegion's type depends on the array region's rvalue type. If it was | 
 | 22 | // a pointer type, we would get a loc::SymbolVal for '*p'. | 
| Eli Friedman | 0b308ad | 2009-06-04 19:35:30 +0000 | [diff] [blame] | 23 | void* memchr(); | 
| Zhongxing Xu | 3c4b379 | 2009-03-11 09:15:38 +0000 | [diff] [blame] | 24 | static int | 
 | 25 | domain_port (const char *domain_b, const char *domain_e, | 
 | 26 |              const char **domain_e_ptr) | 
 | 27 | { | 
 | 28 |   int port = 0; | 
 | 29 |    | 
 | 30 |   const char *p; | 
 | 31 |   const char *colon = memchr (domain_b, ':', domain_e - domain_b); | 
 | 32 |    | 
 | 33 |   for (p = colon + 1; p < domain_e ; p++) | 
 | 34 |     port = 10 * port + (*p - '0'); | 
 | 35 |   return port; | 
 | 36 | } | 
| Zhongxing Xu | 3ce2dc3 | 2009-11-09 05:34:10 +0000 | [diff] [blame] | 37 |  | 
 | 38 | void f3() { | 
 | 39 |   int x, y; | 
 | 40 |   int d = &y - &x; // expected-warning{{Subtraction of two pointers that do not point to the same memory chunk may cause incorrect result.}} | 
| Zhongxing Xu | adca271 | 2009-11-10 02:37:53 +0000 | [diff] [blame] | 41 |  | 
 | 42 |   int a[10]; | 
 | 43 |   int *p = &a[2]; | 
 | 44 |   int *q = &a[8]; | 
 | 45 |   d = q-p; // no-warning | 
| Zhongxing Xu | 3ce2dc3 | 2009-11-09 05:34:10 +0000 | [diff] [blame] | 46 | } | 
| Zhongxing Xu | b10a7c2 | 2009-11-09 06:52:44 +0000 | [diff] [blame] | 47 |  | 
 | 48 | void f4() { | 
 | 49 |   int *p; | 
 | 50 |   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.}} | 
 | 51 | } | 
| Zhongxing Xu | ede7eb2 | 2009-11-09 13:23:31 +0000 | [diff] [blame] | 52 |  | 
 | 53 | void f5() { | 
 | 54 |   int x, y; | 
 | 55 |   int *p; | 
| Zhongxing Xu | e4da0eb | 2009-11-09 13:56:44 +0000 | [diff] [blame] | 56 |   p = &x + 1;  // expected-warning{{Pointer arithmetic done on non-array variables means reliance on memory layout, which is dangerous.}} | 
| Zhongxing Xu | ede7eb2 | 2009-11-09 13:23:31 +0000 | [diff] [blame] | 57 |  | 
 | 58 |   int a[10]; | 
 | 59 |   p = a + 1; // no-warning | 
 | 60 | } | 
| Zhongxing Xu | 79234ca | 2009-11-10 02:45:49 +0000 | [diff] [blame] | 61 |  | 
 | 62 | // Allow arithmetic on different symbolic regions. | 
 | 63 | void f6(int *p, int *q) { | 
 | 64 |   int d = q - p; // no-warning | 
 | 65 | } | 
| Jordy Rose | eac4a00 | 2010-06-28 08:26:15 +0000 | [diff] [blame] | 66 |  | 
 | 67 | void null_operand(int *a) { | 
 | 68 | start: | 
 | 69 |   // LHS is a label, RHS is NULL | 
 | 70 |   if (&&start == 0) | 
 | 71 |     WARN; // no-warning | 
 | 72 |   if (&&start <  0) | 
 | 73 |     WARN; // no-warning | 
 | 74 |   if (&&start <= 0) | 
 | 75 |     WARN; // no-warning | 
 | 76 |   if (!(&&start != 0)) | 
 | 77 |     WARN; // no-warning | 
 | 78 |   if (!(&&start >  0)) | 
 | 79 |     WARN; // no-warning | 
 | 80 |   if (!(&&start >= 0)) | 
 | 81 |     WARN; // no-warning | 
 | 82 |   if (!(&&start - 0)) | 
 | 83 |     WARN; // no-warning | 
 | 84 |  | 
 | 85 |   // LHS is a non-symbolic value, RHS is NULL | 
 | 86 |   if (&a == 0) | 
 | 87 |     WARN; // no-warning | 
 | 88 |   if (&a <  0) | 
 | 89 |     WARN; // no-warning | 
 | 90 |   if (&a <= 0) | 
 | 91 |     WARN; // no-warning | 
 | 92 |   if (!(&a != 0)) | 
 | 93 |     WARN; // no-warning | 
 | 94 |   if (!(&a >  0)) | 
 | 95 |     WARN; // no-warning | 
 | 96 |   if (!(&a >= 0)) | 
 | 97 |     WARN; // no-warning | 
 | 98 |  | 
 | 99 |   if (!(&a - 0)) // expected-warning{{Pointer arithmetic done on non-array variables}} | 
 | 100 |     WARN; // no-warning | 
 | 101 |  | 
 | 102 |   // LHS is NULL, RHS is non-symbolic | 
 | 103 |   // The same code is used for labels and non-symbolic values. | 
 | 104 |   if (0 == &a) | 
 | 105 |     WARN; // no-warning | 
 | 106 |   if (0 >  &a) | 
 | 107 |     WARN; // no-warning | 
 | 108 |   if (0 >= &a) | 
 | 109 |     WARN; // no-warning | 
 | 110 |   if (!(0 != &a)) | 
 | 111 |     WARN; // no-warning | 
 | 112 |   if (!(0 <  &a)) | 
 | 113 |     WARN; // no-warning | 
 | 114 |   if (!(0 <= &a)) | 
 | 115 |     WARN; // no-warning | 
 | 116 |  | 
 | 117 |   // LHS is a symbolic value, RHS is NULL | 
 | 118 |   if (a == 0) | 
 | 119 |     WARN; // expected-warning{{}} | 
 | 120 |   if (a <  0) | 
 | 121 |     WARN; // no-warning | 
 | 122 |   if (a <= 0) | 
 | 123 |     WARN; // expected-warning{{}} | 
 | 124 |   if (!(a != 0)) | 
 | 125 |     WARN; // expected-warning{{}} | 
 | 126 |   if (!(a >  0)) | 
 | 127 |     WARN; // expected-warning{{}} | 
 | 128 |   if (!(a >= 0)) | 
 | 129 |     WARN; // no-warning | 
 | 130 |   if (!(a - 0)) | 
 | 131 |     WARN; // expected-warning{{}} | 
 | 132 |  | 
 | 133 |   // LHS is NULL, RHS is a symbolic value | 
 | 134 |   if (0 == a) | 
 | 135 |     WARN; // expected-warning{{}} | 
 | 136 |   if (0 >  a) | 
 | 137 |     WARN; // no-warning | 
 | 138 |   if (0 >= a) | 
 | 139 |     WARN; // expected-warning{{}} | 
 | 140 |   if (!(0 != a)) | 
 | 141 |     WARN; // expected-warning{{}} | 
 | 142 |   if (!(0 <  a)) | 
 | 143 |     WARN; // expected-warning{{}} | 
 | 144 |   if (!(0 <= a)) | 
 | 145 |     WARN; // no-warning | 
 | 146 | } | 
 | 147 |  | 
 | 148 | void const_locs() { | 
 | 149 |   char *a = (char*)0x1000; | 
 | 150 |   char *b = (char*)0x1100; | 
 | 151 | start: | 
 | 152 |   if (a==b) | 
 | 153 |     WARN; // no-warning | 
 | 154 |   if (!(a!=b)) | 
 | 155 |     WARN; // no-warning | 
 | 156 |   if (a>b) | 
 | 157 |     WARN; // no-warning | 
 | 158 |   if (b<a) | 
 | 159 |     WARN; // no-warning | 
 | 160 |   if (a>=b) | 
 | 161 |     WARN; // no-warning | 
 | 162 |   if (b<=a) | 
 | 163 |     WARN; // no-warning | 
 | 164 |   if (b-a != 0x100) | 
 | 165 |     WARN; // no-warning | 
 | 166 |  | 
 | 167 |   if (&&start == a) | 
 | 168 |     WARN; // expected-warning{{}} | 
 | 169 |   if (a == &&start) | 
 | 170 |     WARN; // expected-warning{{}} | 
 | 171 |   if (&a == (char**)a) | 
 | 172 |     WARN; // expected-warning{{}} | 
 | 173 |   if ((char**)a == &a) | 
 | 174 |     WARN; // expected-warning{{}} | 
 | 175 | } | 
 | 176 |  | 
 | 177 | void array_matching_types() { | 
 | 178 |   int array[10]; | 
 | 179 |   int *a = &array[2]; | 
 | 180 |   int *b = &array[5]; | 
 | 181 |  | 
 | 182 |   if (a==b) | 
 | 183 |     WARN; // no-warning | 
 | 184 |   if (!(a!=b)) | 
 | 185 |     WARN; // no-warning | 
 | 186 |   if (a>b) | 
 | 187 |     WARN; // no-warning | 
 | 188 |   if (b<a) | 
 | 189 |     WARN; // no-warning | 
 | 190 |   if (a>=b) | 
 | 191 |     WARN; // no-warning | 
 | 192 |   if (b<=a) | 
 | 193 |     WARN; // no-warning | 
 | 194 |   if ((b-a) == 0) | 
 | 195 |     WARN; // no-warning | 
 | 196 | } | 
 | 197 |  | 
 | 198 | // This takes a different code path than array_matching_types() | 
 | 199 | void array_different_types() { | 
 | 200 |   int array[10]; | 
 | 201 |   int *a = &array[2]; | 
 | 202 |   char *b = (char*)&array[5]; | 
 | 203 |  | 
 | 204 |   if (a==b) // expected-warning{{comparison of distinct pointer types}} | 
 | 205 |     WARN; // no-warning | 
 | 206 |   if (!(a!=b)) // expected-warning{{comparison of distinct pointer types}} | 
 | 207 |     WARN; // no-warning | 
 | 208 |   if (a>b) // expected-warning{{comparison of distinct pointer types}} | 
 | 209 |     WARN; // no-warning | 
 | 210 |   if (b<a) // expected-warning{{comparison of distinct pointer types}} | 
 | 211 |     WARN; // no-warning | 
 | 212 |   if (a>=b) // expected-warning{{comparison of distinct pointer types}} | 
 | 213 |     WARN; // no-warning | 
 | 214 |   if (b<=a) // expected-warning{{comparison of distinct pointer types}} | 
 | 215 |     WARN; // no-warning | 
 | 216 | } | 
 | 217 |  | 
 | 218 | struct test { int x; int y; }; | 
 | 219 | void struct_fields() { | 
 | 220 |   struct test a, b; | 
 | 221 |  | 
 | 222 |   if (&a.x == &a.y) | 
 | 223 |     WARN; // no-warning | 
 | 224 |   if (!(&a.x != &a.y)) | 
 | 225 |     WARN; // no-warning | 
 | 226 |   if (&a.x > &a.y) | 
 | 227 |     WARN; // no-warning | 
 | 228 |   if (&a.y < &a.x) | 
 | 229 |     WARN; // no-warning | 
 | 230 |   if (&a.x >= &a.y) | 
 | 231 |     WARN; // no-warning | 
 | 232 |   if (&a.y <= &a.x) | 
 | 233 |     WARN; // no-warning | 
 | 234 |  | 
 | 235 |   if (&a.x == &b.x) | 
 | 236 |     WARN; // no-warning | 
 | 237 |   if (!(&a.x != &b.x)) | 
 | 238 |     WARN; // no-warning | 
 | 239 |   if (&a.x > &b.x) | 
 | 240 |     WARN; // expected-warning{{}} | 
 | 241 |   if (&b.x < &a.x) | 
 | 242 |     WARN; // expected-warning{{}} | 
 | 243 |   if (&a.x >= &b.x) | 
 | 244 |     WARN; // expected-warning{{}} | 
 | 245 |   if (&b.x <= &a.x) | 
 | 246 |     WARN; // expected-warning{{}} | 
 | 247 | } | 
 | 248 |  | 
 | 249 | void mixed_region_types() { | 
 | 250 |   struct test s; | 
 | 251 |   int array[2]; | 
 | 252 |   void *a = &array, *b = &s; | 
 | 253 |  | 
 | 254 |   if (&a == &b) | 
 | 255 |     WARN; // no-warning | 
 | 256 |   if (!(&a != &b)) | 
 | 257 |     WARN; // no-warning | 
 | 258 |   if (&a > &b) | 
 | 259 |     WARN; // expected-warning{{}} | 
 | 260 |   if (&b < &a) | 
 | 261 |     WARN; // expected-warning{{}} | 
 | 262 |   if (&a >= &b) | 
 | 263 |     WARN; // expected-warning{{}} | 
 | 264 |   if (&b <= &a) | 
 | 265 |     WARN; // expected-warning{{}} | 
 | 266 | } | 
 | 267 |  | 
 | 268 | void symbolic_region(int *p) { | 
 | 269 |   int a; | 
 | 270 |  | 
 | 271 |   if (&a == p) | 
 | 272 |     WARN; // expected-warning{{}} | 
 | 273 |   if (&a != p) | 
 | 274 |     WARN; // expected-warning{{}} | 
 | 275 |   if (&a > p) | 
 | 276 |     WARN; // expected-warning{{}} | 
 | 277 |   if (&a < p) | 
 | 278 |     WARN; // expected-warning{{}} | 
 | 279 |   if (&a >= p) | 
 | 280 |     WARN; // expected-warning{{}} | 
 | 281 |   if (&a <= p) | 
 | 282 |     WARN; // expected-warning{{}} | 
 | 283 | } | 
| Jordy Rose | a274148 | 2010-06-30 01:35:20 +0000 | [diff] [blame] | 284 |  | 
 | 285 | void PR7527 (int *p) { | 
 | 286 |   if (((int) p) & 1) // not crash | 
 | 287 |     return; | 
 | 288 | } |