misc-ps-region-store.m revision 7344c878a73418cfade56e0c2281ac7324a609b2
1// RUN: clang-cc -triple i386-apple-darwin9 -analyze -checker-cfref --analyzer-store=region --verify -fblocks %s &&
2// RUN: clang-cc -triple x86_64-apple-darwin9 -analyze -checker-cfref --analyzer-store=region --verify -fblocks %s
3
4typedef struct objc_selector *SEL;
5typedef signed char BOOL;
6typedef int NSInteger;
7typedef unsigned int NSUInteger;
8typedef struct _NSZone NSZone;
9@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
10@protocol NSObject  - (BOOL)isEqual:(id)object; @end
11@protocol NSCopying  - (id)copyWithZone:(NSZone *)zone; @end
12@protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone; @end
13@protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder; @end
14@interface NSObject <NSObject> {} - (id)init; @end
15extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
16@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
17- (NSUInteger)length;
18+ (id)stringWithUTF8String:(const char *)nullTerminatedCString;
19@end extern NSString * const NSBundleDidLoadNotification;
20@interface NSAssertionHandler : NSObject {}
21+ (NSAssertionHandler *)currentHandler;
22- (void)handleFailureInMethod:(SEL)selector object:(id)object file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format,...;
23@end
24extern NSString * const NSConnectionReplyMode;
25
26
27//---------------------------------------------------------------------------
28// Test case 'checkaccess_union' differs for region store and basic store.
29// The basic store doesn't reason about compound literals, so the code
30// below won't fire an "uninitialized value" warning.
31//---------------------------------------------------------------------------
32
33// PR 2948 (testcase; crash on VisitLValue for union types)
34// http://llvm.org/bugs/show_bug.cgi?id=2948
35void checkaccess_union() {
36  int ret = 0, status;
37  // Since RegionStore doesn't handle unions yet,
38  // this branch condition won't be triggered
39  // as involving an uninitialized value.  
40  if (((((__extension__ (((union {  // no-warning
41    __typeof (status) __in; int __i;}
42    )
43    {
44      .__in = (status)}
45      ).__i))) & 0xff00) >> 8) == 1)
46        ret = 1;
47}
48
49// Check our handling of fields being invalidated by function calls.
50struct test2_struct { int x; int y; char* s; };
51void test2_helper(struct test2_struct* p);
52
53char test2() {
54  struct test2_struct s;
55  test2_help(&s);
56  char *p = 0;
57  
58  if (s.x > 1) {
59    if (s.s != 0) {
60      p = "hello";
61    }
62  }
63  
64  if (s.x > 1) {
65    if (s.s != 0) {
66      return *p;
67    }
68  }
69
70  return 'a';
71}
72
73// BasicStore handles this case incorrectly because it doesn't reason about
74// the value pointed to by 'x' and thus creates different symbolic values
75// at the declarations of 'a' and 'b' respectively.  RegionStore handles
76// it correctly. See the companion test in 'misc-ps-basic-store.m'.
77void test_trivial_symbolic_comparison_pointer_parameter(int *x) {
78  int a = *x;
79  int b = *x;
80  if (a != b) {
81    int *p = 0;
82    *p = 0xDEADBEEF;     // no-warning
83  }
84}
85
86// This is a modified test from 'misc-ps.m'.  Here we have the extra
87// NULL dereferences which are pruned out by RegionStore's symbolic reasoning
88// of fields.
89typedef struct _BStruct { void *grue; } BStruct;
90void testB_aux(void *ptr);
91
92void testB(BStruct *b) {
93  {
94    int *__gruep__ = ((int *)&((b)->grue));
95    int __gruev__ = *__gruep__;
96    int __gruev2__ = *__gruep__;
97    if (__gruev__ != __gruev2__) {
98      int *p = 0;
99      *p = 0xDEADBEEF; // no-warning
100    }
101
102    testB_aux(__gruep__);
103  }
104  {
105    int *__gruep__ = ((int *)&((b)->grue));
106    int __gruev__ = *__gruep__;
107    int __gruev2__ = *__gruep__;
108    if (__gruev__ != __gruev2__) {
109      int *p = 0;
110      *p = 0xDEADBEEF; // no-warning
111    }
112
113    if (~0 != __gruev__) {}
114  }
115}
116
117void testB_2(BStruct *b) {
118  {
119    int **__gruep__ = ((int **)&((b)->grue));
120    int *__gruev__ = *__gruep__;
121    testB_aux(__gruep__);
122  }
123  {
124    int **__gruep__ = ((int **)&((b)->grue));
125    int *__gruev__ = *__gruep__;
126    if ((int*)~0 != __gruev__) {}
127  }
128}
129
130// This test case is a reduced case of a caching bug discovered by an
131// assertion failure in RegionStoreManager::BindArray.  Essentially the
132// DeclStmt is evaluated twice, but on the second loop iteration the
133// engine caches out.  Previously a false transition would cause UnknownVal
134// to bind to the variable, firing an assertion failure.  This bug was fixed
135// in r76262.
136void test_declstmt_caching() {
137again:
138  {
139    const char a[] = "I like to crash";
140    goto again;
141  }
142}
143
144//===----------------------------------------------------------------------===//
145// Reduced test case from <rdar://problem/7114618>.
146// Basically a null check is performed on the field value, which is then
147// assigned to a variable and then checked again.
148//===----------------------------------------------------------------------===//
149struct s_7114618 { int *p; };
150void test_rdar_7114618(struct s_7114618 *s) {
151  if (s->p) {
152    int *p = s->p;
153    if (!p) {
154      // Infeasible
155      int *dead = 0;
156      *dead = 0xDEADBEEF; // no-warning
157    }
158  }
159}
160
161// Test pointers increment correctly.
162void f() {
163  int a[2];
164  a[1] = 3;
165  int *p = a;
166  p++;
167  if (*p != 3) {
168    int *q = 0;
169    *q = 3; // no-warning
170  }
171}
172
173//===----------------------------------------------------------------------===//
174// <rdar://problem/7185607>
175// Bit-fields of a struct should be invalidated when blasting the entire
176// struct with an integer constant.
177//===----------------------------------------------------------------------===//
178struct test_7185607 {
179  int x : 10;
180  int y : 22;
181};
182int rdar_test_7185607() {
183  struct test_7185607 s; // Uninitialized.
184  *((unsigned *) &s) = 0U;
185  return s.x; // no-warning
186}
187
188//===----------------------------------------------------------------------===//
189// <rdar://problem/7242006> [RegionStore] compound literal assignment with
190//  floats not honored
191// This test case is mirrored in misc-ps.m, but this case is a negative.
192//===----------------------------------------------------------------------===//
193typedef float CGFloat;
194typedef struct _NSSize {
195    CGFloat width;
196    CGFloat height;
197} NSSize;
198
199CGFloat rdar7242006_negative(CGFloat x) {
200  NSSize y;
201  return y.width; // expected-warning{{garbage}}
202}
203
204//===----------------------------------------------------------------------===//
205// <rdar://problem/7249340> - Allow binding of values to symbolic regions.
206// This test case shows how RegionStore tracks the value bound to 'x'
207// after the assignment.
208//===----------------------------------------------------------------------===//
209typedef int* ptr_rdar_7249340;
210void rdar_7249340(ptr_rdar_7249340 x) {
211  *x = 1;
212  if (*x)
213    return;
214  int *p = 0;   // This is unreachable.
215  *p = 0xDEADBEEF; // no-warning
216}
217
218//===----------------------------------------------------------------------===//
219// <rdar://problem/7249327> - This test case tests both value tracking of
220// array values and that we handle symbolic values that are casted
221// between different integer types.  Note the assignment 'n = *a++'; here
222// 'n' is and 'int' and '*a' is 'unsigned'.  Previously we got a false positive
223// at 'x += *b++' (undefined value) because we got a false path.
224//===----------------------------------------------------------------------===//
225int rdar_7249327_aux(void);
226
227void rdar_7249327(unsigned int A[2*32]) {
228  int B[2*32];
229  int *b;
230  unsigned int *a;
231  int x = 0;
232  
233  int n;
234  
235  a = A;
236  b = B;
237  
238  n = *a++;
239  if (n)
240    *b++ = rdar_7249327_aux();
241
242  a = A;
243  b = B;
244  
245  n = *a++;
246  if (n)
247    x += *b++; // no-warning
248}
249
250//===----------------------------------------------------------------------===//
251// <rdar://problem/6914474> - Check that 'x' is invalidated because its
252// address is passed in as a value to a struct.
253//===----------------------------------------------------------------------===//
254struct doodad_6914474 { int *v; };
255extern void prod_6914474(struct doodad_6914474 *d);
256int rdar_6914474(void) {
257  int x;
258  struct doodad_6914474 d;
259  d.v = &x;
260  prod_6914474(&d);
261  return x; // no-warning
262}
263
264// Test invalidation of a single field.
265struct s_test_field_invalidate {
266  int x;
267};
268extern void test_invalidate_field(int *x);
269int test_invalidate_field_test() {
270  struct s_test_field_invalidate y;
271  test_invalidate_field(&y.x);
272  return y.x; // no-warning
273}
274int test_invalidate_field_test_positive() {
275  struct s_test_field_invalidate y;
276  return y.x; // expected-warning{{garbage}}
277}
278
279// This test case illustrates how a typeless array of bytes casted to a
280// struct should be treated as initialized.  RemoveDeadBindings previously
281// had a bug that caused 'x' to lose its default symbolic value after the
282// assignment to 'p', thus causing 'p->z' to evaluate to "undefined".
283struct ArrayWrapper { unsigned char y[16]; };
284struct WrappedStruct { unsigned z; };
285
286int test_handle_array_wrapper() {
287  struct ArrayWrapper x;
288  test_handle_array_wrapper(&x);
289  struct WrappedStruct *p = (struct WrappedStruct*) x.y;
290  return p->z;  // no-warning
291}
292
293//===----------------------------------------------------------------------===//
294// <rdar://problem/7261075> [RegionStore] crash when 
295//   handling load: '*((unsigned int *)"????")'
296//===----------------------------------------------------------------------===//
297
298int rdar_7261075(void) {
299  unsigned int var = 0;
300  if (var == *((unsigned int *)"????"))
301    return 1;
302  return 0;
303}
304
305//===----------------------------------------------------------------------===//
306// <rdar://problem/7275774> false path due to limited pointer 
307//                          arithmetic constraints
308//===----------------------------------------------------------------------===//
309
310void rdar_7275774(void *data, unsigned n) {
311  if (!(data || n == 0))
312    return;
313  
314  unsigned short *p = (unsigned short*) data;
315  unsigned short *q = p + (n / 2);
316
317  if (p < q) {
318    // If we reach here, 'p' cannot be null.  If 'p' is null, then 'n' must
319    // be '0', meaning that this branch is not feasible.
320    *p = *q; // no-warning
321  }
322}
323
324//===----------------------------------------------------------------------===//
325// <rdar://problem/7312221>
326//
327//  Test that Objective-C instance variables aren't prematurely pruned
328//  from the analysis state.
329//===----------------------------------------------------------------------===//
330
331struct rdar_7312221_value { int x; };
332
333@interface RDar7312221
334{
335  struct rdar_7312221_value *y;
336}
337- (void) doSomething_7312221;
338@end
339
340extern struct rdar_7312221_value *rdar_7312221_helper();
341extern int rdar_7312221_helper_2(id o);
342extern void rdar_7312221_helper_3(int z);
343
344@implementation RDar7312221
345- (void) doSomething_7312221 {
346  if (y == 0) {
347    y = rdar_7312221_helper();
348    if (y != 0) {
349      y->x = rdar_7312221_helper_2(self);
350      // The following use of 'y->x' previously triggered a null dereference, as the value of 'y'
351      // before 'y = rdar_7312221_helper()' would be used.
352      rdar_7312221_helper_3(y->x); // no-warning
353    }
354  }
355}
356@end
357
358struct rdar_7312221_container {
359  struct rdar_7312221_value *y;
360};
361
362extern int rdar_7312221_helper_4(struct rdar_7312221_container *s);
363
364// This test case essentially matches the one in [RDar7312221 doSomething_7312221].
365void doSomething_7312221_with_struct(struct rdar_7312221_container *Self) {
366  if (Self->y == 0) {
367    Self->y = rdar_7312221_helper();
368    if (Self->y != 0) {
369      Self->y->x = rdar_7312221_helper_4(Self);
370      rdar_7312221_helper_3(Self->y->x); // no-warning
371    }
372  }
373}
374
375//===----------------------------------------------------------------------===//
376// <rdar://problem/7332673> - Just more tests cases for regions
377//===----------------------------------------------------------------------===//
378
379void rdar_7332673_test1() {
380    char value[1];
381    if ( *(value) != 1 ) {} // expected-warning{{The left operand of '!=' is a garbage value}}
382}
383void rdar_rdar_7332673_test2_aux(char *x);
384void rdar_7332673_test2() {
385    char *value;
386    if ( rdar_7332673_test2_aux(value) != 1 ) {} // expected-warning{{Pass-by-value argument in function call is undefined}}
387}
388
389//===----------------------------------------------------------------------===//
390// <rdar://problem/7347252>: Because of a bug in
391//   RegionStoreManager::RemoveDeadBindings(), the symbol for s->session->p
392//   would incorrectly be pruned from the state after the call to
393//   rdar7347252_malloc1(), and would incorrectly result in a warning about
394//   passing a null pointer to rdar7347252_memcpy().
395//===----------------------------------------------------------------------===//
396
397struct rdar7347252_AA { char *p;};
398typedef struct {
399 struct rdar7347252_AA *session;
400 int t;
401 char *q;
402} rdar7347252_SSL1;
403
404int rdar7347252_f(rdar7347252_SSL1 *s);
405char *rdar7347252_malloc1(int);
406char *rdar7347252_memcpy1(char *d, char *s, int n) __attribute__((nonnull (1,2)));
407
408int rdar7347252(rdar7347252_SSL1 *s) {
409 rdar7347252_f(s);  // the SymbolicRegion of 's' is set a default binding of conjured symbol
410 if (s->session->p == ((void*)0)) {
411   if ((s->session->p = rdar7347252_malloc1(10)) == ((void*)0)) {
412     return 0;
413   }
414   rdar7347252_memcpy1(s->session->p, "aa", 2); // no-warning
415 }
416 return 0;
417}
418
419//===----------------------------------------------------------------------===//
420// PR 5316 - "crash when accessing field of lazy compound value"
421//  Previously this caused a crash at the MemberExpr '.chr' when loading
422//  a field value from a LazyCompoundVal
423//===----------------------------------------------------------------------===//
424
425typedef unsigned int pr5316_wint_t;
426typedef pr5316_wint_t pr5316_REFRESH_CHAR;
427typedef struct {
428  pr5316_REFRESH_CHAR chr;
429}
430pr5316_REFRESH_ELEMENT;
431static void pr5316(pr5316_REFRESH_ELEMENT *dst, const pr5316_REFRESH_ELEMENT *src) {
432  while ((*dst++ = *src++).chr != L'\0')  ;
433}
434
435//===----------------------------------------------------------------------===//
436// Exercise creating ElementRegion with symbolic super region.
437//===----------------------------------------------------------------------===//
438void element_region_with_symbolic_superregion(int* p) {
439  int *x;
440  int a;
441  if (p[0] == 1)
442    x = &a;
443  if (p[0] == 1)
444    (void)*x; // no-warning
445}
446
447//===----------------------------------------------------------------------===//
448// Test returning an out-of-bounds pointer (CWE-466)
449//===----------------------------------------------------------------------===//
450
451static int test_cwe466_return_outofbounds_pointer_a[10];
452int *test_cwe466_return_outofbounds_pointer() {
453  int *p = test_cwe466_return_outofbounds_pointer_a+10;
454  return p; // expected-warning{{Returned pointer value points outside the original object}}
455}
456
457//===----------------------------------------------------------------------===//
458// PR 3135 - Test case that shows that a variable may get invalidated when its
459// address is included in a structure that is passed-by-value to an unknown function.
460//===----------------------------------------------------------------------===//
461
462typedef struct { int *a; } pr3135_structure;
463int pr3135_bar(pr3135_structure *x);
464int pr3135() {
465  int x;
466  pr3135_structure y = { &x };
467  // the call to pr3135_bar may initialize x
468  if (pr3135_bar(&y) && x) // no-warning
469    return 1;
470  return 0;
471}
472
473