1// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,debug.ExprInspection -analyzer-store=region -verify -triple x86_64-apple-darwin9 %s 2// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,debug.ExprInspection -analyzer-store=region -verify -triple i686-apple-darwin9 %s 3 4void clang_analyzer_eval(int); 5 6void f1() { 7 int a[10]; 8 int *p = a; 9 ++p; 10} 11 12char* foo(); 13 14void f2() { 15 char *p = foo(); 16 ++p; 17} 18 19// This test case checks if we get the right rvalue type of a TypedViewRegion. 20// The ElementRegion's type depends on the array region's rvalue type. If it was 21// a pointer type, we would get a loc::SymbolVal for '*p'. 22void* memchr(); 23static int 24domain_port (const char *domain_b, const char *domain_e, 25 const char **domain_e_ptr) 26{ 27 int port = 0; 28 29 const char *p; 30 const char *colon = memchr (domain_b, ':', domain_e - domain_b); 31 32 for (p = colon + 1; p < domain_e ; p++) 33 port = 10 * port + (*p - '0'); 34 return port; 35} 36 37void f3() { 38 int x, y; 39 int d = &y - &x; // expected-warning{{Subtraction of two pointers that do not point to the same memory chunk may cause incorrect result}} 40 41 int a[10]; 42 int *p = &a[2]; 43 int *q = &a[8]; 44 d = q-p; // no-warning 45} 46 47void f4() { 48 int *p; 49 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}} 50} 51 52void f5() { 53 int x, y; 54 int *p; 55 p = &x + 1; // expected-warning{{Pointer arithmetic done on non-array variables means reliance on memory layout, which is dangerous}} 56 57 int a[10]; 58 p = a + 1; // no-warning 59} 60 61// Allow arithmetic on different symbolic regions. 62void f6(int *p, int *q) { 63 int d = q - p; // no-warning 64} 65 66void null_operand(int *a) { 67start: 68 // LHS is a label, RHS is NULL 69 clang_analyzer_eval(&&start != 0); // expected-warning{{TRUE}} 70 clang_analyzer_eval(&&start >= 0); // expected-warning{{TRUE}} 71 clang_analyzer_eval(&&start > 0); // expected-warning{{TRUE}} 72 clang_analyzer_eval((&&start - 0) != 0); // expected-warning{{TRUE}} 73 74 // LHS is a non-symbolic value, RHS is NULL 75 clang_analyzer_eval(&a != 0); // expected-warning{{TRUE}} 76 clang_analyzer_eval(&a >= 0); // expected-warning{{TRUE}} 77 clang_analyzer_eval(&a > 0); // expected-warning{{TRUE}} 78 clang_analyzer_eval((&a - 0) != 0); // expected-warning{{TRUE}} expected-warning{{Pointer arithmetic done on non-array variables}} 79 80 // LHS is NULL, RHS is non-symbolic 81 // The same code is used for labels and non-symbolic values. 82 clang_analyzer_eval(0 != &a); // expected-warning{{TRUE}} 83 clang_analyzer_eval(0 <= &a); // expected-warning{{TRUE}} 84 clang_analyzer_eval(0 < &a); // expected-warning{{TRUE}} 85 86 // LHS is a symbolic value, RHS is NULL 87 clang_analyzer_eval(a != 0); // expected-warning{{UNKNOWN}} 88 clang_analyzer_eval(a >= 0); // expected-warning{{TRUE}} 89 clang_analyzer_eval(a <= 0); // expected-warning{{UNKNOWN}} 90 clang_analyzer_eval((a - 0) != 0); // expected-warning{{UNKNOWN}} 91 92 // LHS is NULL, RHS is a symbolic value 93 clang_analyzer_eval(0 != a); // expected-warning{{UNKNOWN}} 94 clang_analyzer_eval(0 <= a); // expected-warning{{TRUE}} 95 clang_analyzer_eval(0 < a); // expected-warning{{UNKNOWN}} 96} 97 98void const_locs() { 99 char *a = (char*)0x1000; 100 char *b = (char*)0x1100; 101start: 102 clang_analyzer_eval(a != b); // expected-warning{{TRUE}} 103 clang_analyzer_eval(a < b); // expected-warning{{TRUE}} 104 clang_analyzer_eval(a <= b); // expected-warning{{TRUE}} 105 clang_analyzer_eval((b-a) == 0x100); // expected-warning{{TRUE}} 106 107 clang_analyzer_eval(&&start == a); // expected-warning{{UNKNOWN}} 108 clang_analyzer_eval(a == &&start); // expected-warning{{UNKNOWN}} 109 clang_analyzer_eval(&a == (char**)a); // expected-warning{{UNKNOWN}} 110 clang_analyzer_eval((char**)a == &a); // expected-warning{{UNKNOWN}} 111} 112 113void array_matching_types() { 114 int array[10]; 115 int *a = &array[2]; 116 int *b = &array[5]; 117 118 clang_analyzer_eval(a != b); // expected-warning{{TRUE}} 119 clang_analyzer_eval(a < b); // expected-warning{{TRUE}} 120 clang_analyzer_eval(a <= b); // expected-warning{{TRUE}} 121 clang_analyzer_eval((b-a) != 0); // expected-warning{{TRUE}} 122} 123 124// This takes a different code path than array_matching_types() 125void array_different_types() { 126 int array[10]; 127 int *a = &array[2]; 128 char *b = (char*)&array[5]; 129 130 clang_analyzer_eval(a != b); // expected-warning{{TRUE}} expected-warning{{comparison of distinct pointer types}} 131 clang_analyzer_eval(a < b); // expected-warning{{TRUE}} expected-warning{{comparison of distinct pointer types}} 132 clang_analyzer_eval(a <= b); // expected-warning{{TRUE}} expected-warning{{comparison of distinct pointer types}} 133} 134 135struct test { int x; int y; }; 136void struct_fields() { 137 struct test a, b; 138 139 clang_analyzer_eval(&a.x != &a.y); // expected-warning{{TRUE}} 140 clang_analyzer_eval(&a.x < &a.y); // expected-warning{{TRUE}} 141 clang_analyzer_eval(&a.x <= &a.y); // expected-warning{{TRUE}} 142 143 clang_analyzer_eval(&a.x != &b.x); // expected-warning{{TRUE}} 144 clang_analyzer_eval(&a.x > &b.x); // expected-warning{{UNKNOWN}} 145 clang_analyzer_eval(&a.x >= &b.x); // expected-warning{{UNKNOWN}} 146} 147 148void mixed_region_types() { 149 struct test s; 150 int array[2]; 151 void *a = &array, *b = &s; 152 153 clang_analyzer_eval(&a != &b); // expected-warning{{TRUE}} 154 clang_analyzer_eval(&a > &b); // expected-warning{{UNKNOWN}} 155 clang_analyzer_eval(&a >= &b); // expected-warning{{UNKNOWN}} 156} 157 158void symbolic_region(int *p) { 159 int a; 160 161 clang_analyzer_eval(&a != p); // expected-warning{{TRUE}} 162 clang_analyzer_eval(&a > p); // expected-warning{{UNKNOWN}} 163 clang_analyzer_eval(&a >= p); // expected-warning{{UNKNOWN}} 164} 165 166void PR7527 (int *p) { 167 if (((int) p) & 1) // not crash 168 return; 169} 170