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