null-deref-ps.c revision 339d52a8ddcb345275ec48c7bab849a8943fa9f5
1// RUN: clang-cc -analyze -std=gnu99 -checker-cfref -verify %s -analyzer-constraints=basic -analyzer-store=basic && 2// RUN: clang-cc -analyze -std=gnu99 -checker-cfref -verify %s -analyzer-constraints=basic -analyzer-store=basic-old-cast && 3// RUN: clang-cc -analyze -std=gnu99 -checker-cfref -verify %s -analyzer-constraints=range -analyzer-store=basic && 4// RUN: clang-cc -analyze -std=gnu99 -checker-cfref -verify %s -analyzer-constraints=range -analyzer-store=basic-old-cast && 5// RUN: clang-cc -analyze -std=gnu99 -checker-cfref -analyzer-store=region -analyzer-constraints=range -analyzer-purge-dead=false -verify %s && 6// RUN: clang-cc -analyze -std=gnu99 -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify %s 7 8#include<stdint.h> 9#include <assert.h> 10 11void f1(int *p) { 12 if (p) *p = 1; 13 else *p = 0; // expected-warning{{ereference}} 14} 15 16struct foo_struct { 17 int x; 18}; 19 20int f2(struct foo_struct* p) { 21 22 if (p) 23 p->x = 1; 24 25 return p->x++; // expected-warning{{Dereference of null pointer.}} 26} 27 28int f3(char* x) { 29 30 int i = 2; 31 32 if (x) 33 return x[i - 1]; 34 35 return x[i+1]; // expected-warning{{Dereference of null pointer.}} 36} 37 38int f3_b(char* x) { 39 40 int i = 2; 41 42 if (x) 43 return x[i - 1]; 44 45 return x[i+1]++; // expected-warning{{Dereference of null pointer.}} 46} 47 48int f4(int *p) { 49 50 uintptr_t x = (uintptr_t) p; 51 52 if (x) 53 return 1; 54 55 int *q = (int*) x; 56 return *q; // expected-warning{{Dereference of null pointer.}} 57} 58 59int f4_b() { 60 short array[2]; 61 uintptr_t x = array; // expected-warning{{incompatible pointer to integer conversion initializing}} 62 short *p = x; // expected-warning{{incompatible integer to pointer conversion initializing}} 63 64 // The following branch should be infeasible. 65 if (!(p = &array[0])) { 66 p = 0; 67 *p = 1; // no-warning 68 } 69 70 if (p) { 71 *p = 5; // no-warning 72 p = 0; 73 } 74 else return; // expected-warning {{non-void function 'f4_b' should return a value}} 75 76 *p += 10; // expected-warning{{Dereference of null pointer}} 77 return 0; 78} 79 80 81int f5() { 82 83 char *s = "hello world"; 84 return s[0]; // no-warning 85} 86 87int bar(int* p, int q) __attribute__((nonnull)); 88 89int f6(int *p) { 90 return !p ? bar(p, 1) // expected-warning {{Null pointer passed as an argument to a 'nonnull' parameter}} 91 : bar(p, 0); // no-warning 92} 93 94int bar2(int* p, int q) __attribute__((nonnull(1))); 95 96int f6b(int *p) { 97 return !p ? bar2(p, 1) // expected-warning {{Null pointer passed as an argument to a 'nonnull' parameter}} 98 : bar2(p, 0); // no-warning 99} 100 101int bar3(int*p, int q, int *r) __attribute__((nonnull(1,3))); 102 103int f6c(int *p, int *q) { 104 return !p ? bar3(q, 2, p) // expected-warning {{Null pointer passed as an argument to a 'nonnull' parameter}} 105 : bar3(p, 2, q); // no-warning 106} 107 108int* qux(); 109 110int f7(int x) { 111 112 int* p = 0; 113 114 if (0 == x) 115 p = qux(); 116 117 if (0 == x) 118 *p = 1; // no-warning 119 120 return x; 121} 122 123int* f7b(int *x) { 124 125 int* p = 0; 126 127 if (((void*)0) == x) 128 p = qux(); 129 130 if (((void*)0) == x) 131 *p = 1; // no-warning 132 133 return x; 134} 135 136int* f7c(int *x) { 137 138 int* p = 0; 139 140 if (((void*)0) == x) 141 p = qux(); 142 143 if (((void*)0) != x) 144 return x; 145 146 // If we reach here then 'p' is not null. 147 *p = 1; // no-warning 148 return x; 149} 150 151int* f7c2(int *x) { 152 153 int* p = 0; 154 155 if (((void*)0) == x) 156 p = qux(); 157 158 if (((void*)0) == x) 159 return x; 160 161 *p = 1; // expected-warning{{null}} 162 return x; 163} 164 165 166void f8(int *p, int *q) { 167 if (!p) 168 if (p) 169 *p = 1; // no-warning 170 171 if (q) 172 if (!q) 173 *q = 1; // no-warning 174} 175 176int* qux(); 177 178int f9(unsigned len) { 179 assert (len != 0); 180 int *p = 0; 181 unsigned i; 182 183 for (i = 0; i < len; ++i) 184 p = qux(i); 185 186 return *p++; // no-warning 187} 188 189int f9b(unsigned len) { 190 assert (len > 0); // note use of '>' 191 int *p = 0; 192 unsigned i; 193 194 for (i = 0; i < len; ++i) 195 p = qux(i); 196 197 return *p++; // no-warning 198} 199 200int* f10(int* p, signed char x, int y) { 201 // This line tests symbolication with compound assignments where the 202 // LHS and RHS have different bitwidths. The new symbolic value 203 // for 'x' should have a bitwidth of 8. 204 x &= y; 205 206 // This tests that our symbolication worked, and that we correctly test 207 // x against 0 (with the same bitwidth). 208 if (!x) { 209 if (!p) return; // expected-warning {{non-void function 'f10' should return a value}} 210 *p = 10; 211 } 212 else p = 0; 213 214 if (!x) 215 *p = 5; // no-warning 216 217 return p; 218} 219 220// Test case from <rdar://problem/6407949> 221void f11(unsigned i) { 222 int *x = 0; 223 if (i >= 0) { 224 // always true 225 } else { 226 *x = 42; // no-warning 227 } 228} 229 230void f11b(unsigned i) { 231 int *x = 0; 232 if (i <= ~(unsigned)0) { 233 // always true 234 } else { 235 *x = 42; // no-warning 236 } 237} 238 239// Test case for switch statements with weird case arms. 240typedef int BOOL, *PBOOL, *LPBOOL; 241typedef long LONG_PTR, *PLONG_PTR; 242typedef unsigned long ULONG_PTR, *PULONG_PTR; 243typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR; 244typedef LONG_PTR LRESULT; 245typedef struct _F12ITEM *HF12ITEM; 246 247void f12(HF12ITEM i, char *q) { 248 char *p = 0; 249 switch ((DWORD_PTR) i) { 250 case 0 ... 10: 251 p = q; 252 break; 253 case (DWORD_PTR) ((HF12ITEM) - 65535): 254 return; 255 default: 256 return; 257 } 258 259 *p = 1; // no-warning 260} 261 262// Test handling of translating between integer "pointers" and back. 263void f13() { 264 int *x = 0; 265 if (((((int) x) << 2) + 1) >> 1) *x = 1; // no-warning 266} 267 268 269