|  | // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -verify %s | 
|  |  | 
|  | extern void __assert_fail (__const char *__assertion, __const char *__file, | 
|  | unsigned int __line, __const char *__function) | 
|  | __attribute__ ((__noreturn__)); | 
|  |  | 
|  | #define assert(expr) \ | 
|  | ((expr)  ? (void)(0)  : __assert_fail (#expr, __FILE__, __LINE__, __func__)) | 
|  |  | 
|  | typedef unsigned long long uintptr_t; | 
|  |  | 
|  | void f0(void) { | 
|  | int *p = (int*) 0x10000; // Should not crash here. | 
|  | *p = 3; // expected-warning{{Dereference of a fixed address}} | 
|  | } | 
|  |  | 
|  | void f1(int *p) { | 
|  | if (p != (int *)-1) | 
|  | *p = 1; | 
|  | else | 
|  | *p = 0; // expected-warning{{Dereference of a fixed address}} | 
|  | } | 
|  |  | 
|  | struct f2_struct { | 
|  | int x; | 
|  | }; | 
|  |  | 
|  | int f2(struct f2_struct* p) { | 
|  |  | 
|  | if (p != (struct f2_struct *)1) | 
|  | p->x = 1; | 
|  |  | 
|  | return p->x++; // expected-warning{{Access to field 'x' results in a dereference of a fixed address (loaded from variable 'p')}} | 
|  | } | 
|  |  | 
|  | int f3_1(char* x) { | 
|  | int i = 2; | 
|  |  | 
|  | if (x != (char *)1) | 
|  | return x[i - 1]; | 
|  |  | 
|  | return x[i+1]; // expected-warning{{Array access (from variable 'x') results in a dereference of a fixed address}} | 
|  | } | 
|  |  | 
|  | int f3_2(char* x) { | 
|  | int i = 2; | 
|  |  | 
|  | if (x != (char *)1) | 
|  | return x[i - 1]; | 
|  |  | 
|  | return x[i+1]++; // expected-warning{{Array access (from variable 'x') results in a dereference of a fixed address}} | 
|  | } | 
|  |  | 
|  | int f4_1(int *p) { | 
|  | uintptr_t x = (uintptr_t) p; | 
|  |  | 
|  | if (x != (uintptr_t)1) | 
|  | return 1; | 
|  |  | 
|  | int *q = (int*) x; | 
|  | return *q; // expected-warning{{Dereference of a fixed address (loaded from variable 'q')}} | 
|  | } | 
|  |  | 
|  | int f4_2(void) { | 
|  | short array[2]; | 
|  | uintptr_t x = (uintptr_t)array; | 
|  | short *p = (short *)x; | 
|  |  | 
|  | // The following branch should be infeasible. | 
|  | if (!(p == &array[0])) { | 
|  | p = (short *)1; | 
|  | *p = 1; // no-warning | 
|  | } | 
|  |  | 
|  | if (p != (short *)1) { | 
|  | *p = 5; // no-warning | 
|  | p = (short *)1; // expected-warning {{Using a fixed address is not portable}} | 
|  | } | 
|  | else return 1; | 
|  |  | 
|  | *p += 10; // expected-warning{{Dereference of a fixed}} | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | int f5(void) { | 
|  | char *s = "hello world"; | 
|  | return s[0]; // no-warning | 
|  | } | 
|  |  | 
|  | void f6(int *p, int *q) { | 
|  | if (p != (int *)1) | 
|  | if (p == (int *)1) | 
|  | *p = 1; // no-warning | 
|  |  | 
|  | if (q == (int *)1) | 
|  | if (q != (int *)1) | 
|  | *q = 1; // no-warning | 
|  | } | 
|  |  | 
|  | int* qux(int); | 
|  |  | 
|  | int f7_1(unsigned len) { | 
|  | assert (len != 0); | 
|  | int *p = (int *)1; | 
|  | unsigned i; | 
|  |  | 
|  | for (i = 0; i < len; ++i) | 
|  | p = qux(i); | 
|  |  | 
|  | return *p++; // no-warning | 
|  | } | 
|  |  | 
|  | int f7_2(unsigned len) { | 
|  | assert (len > 0);  // note use of '>' | 
|  | int *p = (int *)1; | 
|  | unsigned i; | 
|  |  | 
|  | for (i = 0; i < len; ++i) | 
|  | p = qux(i); | 
|  |  | 
|  | return *p++; // no-warning | 
|  | } | 
|  |  | 
|  | struct f8_s { | 
|  | int x; | 
|  | int y[2]; | 
|  | }; | 
|  |  | 
|  | void f8(struct f8_s *s, int coin) { | 
|  | if (s != (struct f8_s *)7) | 
|  | return; | 
|  |  | 
|  | if (coin) | 
|  | s->x = 5; // expected-warning{{Access to field 'x' results in a dereference of a fixed address (loaded from variable 's')}} | 
|  | else | 
|  | s->y[1] = 6; // expected-warning{{Array access (via field 'y') results in a dereference of a fixed address}} | 
|  | } | 
|  |  | 
|  | void f9() { | 
|  | int (*p_function) (char, char) = (int (*)(char, char))0x04040; // FIXME: warn at this initialization | 
|  | p_function = (int (*)(char, char))0x04080; // expected-warning {{Using a fixed address is not portable}} | 
|  | // FIXME: there should be a warning from calling the function pointer with fixed address | 
|  | int x = (*p_function) ('x', 'y'); | 
|  | } |