null-deref-ps.c revision 6c07bdba93b095b66e2c8c82dd5ed458fa8285ea
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} 76 77 78int f5() { 79 80 char *s = "hello world"; 81 return s[0]; // no-warning 82} 83 84int bar(int* p, int q) __attribute__((nonnull)); 85 86int f6(int *p) { 87 return !p ? bar(p, 1) // expected-warning {{Null pointer passed as an argument to a 'nonnull' parameter}} 88 : bar(p, 0); // no-warning 89} 90 91int bar2(int* p, int q) __attribute__((nonnull(1))); 92 93int f6b(int *p) { 94 return !p ? bar2(p, 1) // expected-warning {{Null pointer passed as an argument to a 'nonnull' parameter}} 95 : bar2(p, 0); // no-warning 96} 97 98int bar3(int*p, int q, int *r) __attribute__((nonnull(1,3))); 99 100int f6c(int *p, int *q) { 101 return !p ? bar3(q, 2, p) // expected-warning {{Null pointer passed as an argument to a 'nonnull' parameter}} 102 : bar3(p, 2, q); // no-warning 103} 104 105int* qux(); 106 107int f7(int x) { 108 109 int* p = 0; 110 111 if (0 == x) 112 p = qux(); 113 114 if (0 == x) 115 *p = 1; // no-warning 116 117 return x; 118} 119 120int* f7b(int *x) { 121 122 int* p = 0; 123 124 if (((void*)0) == x) 125 p = qux(); 126 127 if (((void*)0) == x) 128 *p = 1; // no-warning 129 130 return x; 131} 132 133int* f7c(int *x) { 134 135 int* p = 0; 136 137 if (((void*)0) == x) 138 p = qux(); 139 140 if (((void*)0) != x) 141 return x; 142 143 // If we reach here then 'p' is not null. 144 *p = 1; // no-warning 145 return x; 146} 147 148int* f7c2(int *x) { 149 150 int* p = 0; 151 152 if (((void*)0) == x) 153 p = qux(); 154 155 if (((void*)0) == x) 156 return x; 157 158 *p = 1; // expected-warning{{null}} 159 return x; 160} 161 162 163int f8(int *p, int *q) { 164 if (!p) 165 if (p) 166 *p = 1; // no-warning 167 168 if (q) 169 if (!q) 170 *q = 1; // no-warning 171} 172 173int* qux(); 174 175int f9(unsigned len) { 176 assert (len != 0); 177 int *p = 0; 178 unsigned i; 179 180 for (i = 0; i < len; ++i) 181 p = qux(i); 182 183 return *p++; // no-warning 184} 185 186int f9b(unsigned len) { 187 assert (len > 0); // note use of '>' 188 int *p = 0; 189 unsigned i; 190 191 for (i = 0; i < len; ++i) 192 p = qux(i); 193 194 return *p++; // no-warning 195} 196 197int* f10(int* p, signed char x, int y) { 198 // This line tests symbolication with compound assignments where the 199 // LHS and RHS have different bitwidths. The new symbolic value 200 // for 'x' should have a bitwidth of 8. 201 x &= y; 202 203 // This tests that our symbolication worked, and that we correctly test 204 // x against 0 (with the same bitwidth). 205 if (!x) { 206 if (!p) return; // expected-warning {{non-void function 'f10' should return a value}} 207 *p = 10; 208 } 209 else p = 0; 210 211 if (!x) 212 *p = 5; // no-warning 213 214 return p; 215} 216 217// Test case from <rdar://problem/6407949> 218void f11(unsigned i) { 219 int *x = 0; 220 if (i >= 0) { 221 // always true 222 } else { 223 *x = 42; // no-warning 224 } 225} 226 227void f11b(unsigned i) { 228 int *x = 0; 229 if (i <= ~(unsigned)0) { 230 // always true 231 } else { 232 *x = 42; // no-warning 233 } 234} 235 236// Test case for switch statements with weird case arms. 237typedef int BOOL, *PBOOL, *LPBOOL; 238typedef long LONG_PTR, *PLONG_PTR; 239typedef unsigned long ULONG_PTR, *PULONG_PTR; 240typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR; 241typedef LONG_PTR LRESULT; 242typedef struct _F12ITEM *HF12ITEM; 243 244void f12(HF12ITEM i, char *q) { 245 char *p = 0; 246 switch ((DWORD_PTR) i) { 247 case 0 ... 10: 248 p = q; 249 break; 250 case (DWORD_PTR) ((HF12ITEM) - 65535): 251 return; 252 default: 253 return; 254 } 255 256 *p = 1; // no-warning 257} 258 259// Test handling of translating between integer "pointers" and back. 260void f13() { 261 int *x = 0; 262 if (((((int) x) << 2) + 1) >> 1) *x = 1; // no-warning 263} 264 265 266