misc-ps.m revision 968f0a6fe860b7df42d5ea1ab87a55c757507c1c
1// RUN: clang-cc -analyze -checker-cfref --analyzer-store=basic -analyzer-constraints=basic --verify -fblocks %s &&
2// RUN: clang-cc -analyze -checker-cfref --analyzer-store=basic -analyzer-constraints=range --verify -fblocks %s &&
3// RUN: clang-cc -analyze -checker-cfref --analyzer-store=region -analyzer-constraints=basic --verify -fblocks %s &&
4// RUN: clang-cc -analyze -checker-cfref --analyzer-store=region -analyzer-constraints=range --verify -fblocks %s
5
6typedef struct objc_ivar *Ivar;
7typedef struct objc_selector *SEL;
8typedef signed char BOOL;
9typedef int NSInteger;
10typedef unsigned int NSUInteger;
11typedef struct _NSZone NSZone;
12@class NSInvocation, NSArray, NSMethodSignature, NSCoder, NSString, NSEnumerator;
13@protocol NSObject
14- (BOOL)isEqual:(id)object;
15- (id)autorelease;
16@end
17@protocol NSCopying
18- (id)copyWithZone:(NSZone *)zone;
19@end
20@protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone; @end
21@protocol NSCoding
22- (void)encodeWithCoder:(NSCoder *)aCoder;
23@end
24@interface NSObject <NSObject> {}
25- (id)init;
26+ (id)allocWithZone:(NSZone *)zone;
27@end
28extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
29@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
30- (NSUInteger)length;
31+ (id)stringWithUTF8String:(const char *)nullTerminatedCString;
32@end extern NSString * const NSBundleDidLoadNotification;
33@interface NSValue : NSObject <NSCopying, NSCoding>
34- (void)getValue:(void *)value;
35@end
36@interface NSNumber : NSValue
37- (char)charValue;
38- (id)initWithBool:(BOOL)value;
39@end
40@interface NSAssertionHandler : NSObject {}
41+ (NSAssertionHandler *)currentHandler;
42- (void)handleFailureInMethod:(SEL)selector object:(id)object file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format,...;
43@end
44extern NSString * const NSConnectionReplyMode;
45typedef float CGFloat;
46typedef struct _NSPoint {
47    CGFloat x;
48    CGFloat y;
49} NSPoint;
50typedef struct _NSSize {
51    CGFloat width;
52    CGFloat height;
53} NSSize;
54typedef struct _NSRect {
55    NSPoint origin;
56    NSSize size;
57} NSRect;
58
59// Reduced test case from crash in <rdar://problem/6253157>
60@interface A @end
61@implementation A
62- (void)foo:(void (^)(NSObject *x))block {
63  if (!((block != ((void *)0)))) {}
64}
65@end
66
67// Reduced test case from crash in PR 2796;
68//  http://llvm.org/bugs/show_bug.cgi?id=2796
69
70unsigned foo(unsigned x) { return __alignof__((x)) + sizeof(x); }
71
72// Improvement to path-sensitivity involving compound assignments.
73//  Addresses false positive in <rdar://problem/6268365>
74//
75
76unsigned r6268365Aux();
77
78void r6268365() {
79  unsigned x = 0;
80  x &= r6268365Aux();
81  unsigned j = 0;
82    
83  if (x == 0) ++j;
84  if (x == 0) x = x / j; // no-warning
85}
86
87void divzeroassume(unsigned x, unsigned j) {  
88  x /= j;  
89  if (j == 0) x /= 0;     // no-warning
90  if (j == 0) x /= j;     // no-warning
91  if (j == 0) x = x / 0;  // no-warning
92}
93
94void divzeroassumeB(unsigned x, unsigned j) {  
95  x = x / j;  
96  if (j == 0) x /= 0;     // no-warning
97  if (j == 0) x /= j;     // no-warning
98  if (j == 0) x = x / 0;  // no-warning
99}
100
101// InitListExpr processing
102
103typedef float __m128 __attribute__((__vector_size__(16), __may_alias__));
104__m128 return128() {
105  // This compound literal has a Vector type.  We currently just
106  // return UnknownVal.
107  return __extension__(__m128) { 0.0f, 0.0f, 0.0f, 0.0f };
108}
109
110typedef long long __v2di __attribute__ ((__vector_size__ (16)));
111typedef long long __m128i __attribute__ ((__vector_size__ (16), __may_alias__));
112__m128i vec128i(long long __q1, long long __q0) {
113  // This compound literal returns true for both isVectorType() and 
114  // isIntegerType().
115  return __extension__ (__m128i)(__v2di){ __q0, __q1 };
116}
117
118// Zero-sized VLAs.
119void check_zero_sized_VLA(int x) {
120  if (x)
121    return;
122
123  int vla[x]; // expected-warning{{Variable-length array 'vla' has zero elements (undefined behavior)}}
124}
125
126void check_uninit_sized_VLA() {
127  int x;
128  int vla[x]; // expected-warning{{Variable-length array 'vla' garbage value for array size}}
129}
130
131// sizeof(void)
132// - Tests a regression reported in PR 3211: http://llvm.org/bugs/show_bug.cgi?id=3211
133void handle_sizeof_void(unsigned flag) {
134  int* p = 0;
135
136  if (flag) {
137    if (sizeof(void) == 1)
138      return;
139    // Infeasible.
140    *p = 1; // no-warning
141  }
142  
143  void* q;
144  
145  if (!flag) {
146    if (sizeof(*q) == 1)
147      return;
148    // Infeasibe.
149    *p = 1; // no-warning
150  }
151    
152  // Infeasible.
153  *p = 1; // no-warning
154}
155
156// PR 3422
157void pr3422_helper(char *p);
158void pr3422() {
159  char buf[100];
160  char *q = &buf[10];
161  pr3422_helper(&q[1]);
162}
163
164// PR 3543 (handle empty statement expressions)
165void pr_3543(void) {
166  ({});
167}
168
169// <rdar://problem/6611677>
170// This test case test the use of a vector type within an array subscript
171// expression.
172typedef long long __a64vector __attribute__((__vector_size__(8)));
173typedef long long __a128vector __attribute__((__vector_size__(16)));
174static inline __a64vector __attribute__((__always_inline__, __nodebug__))  
175my_test_mm_movepi64_pi64(__a128vector a) {
176  return (__a64vector)a[0];
177}
178
179// Test basic tracking of ivars associated with 'self'.
180@interface SelfIvarTest : NSObject {
181  int flag;
182}
183- (void)test_self_tracking;
184@end
185
186@implementation SelfIvarTest
187- (void)test_self_tracking {
188  char *p = 0;
189  char c;
190
191  if (flag)
192    p = "hello";
193
194  if (flag)
195    c = *p; // no-warning
196}
197@end
198
199// PR 3770
200char pr3770(int x) {
201  int y = x & 0x2;
202  char *p = 0;
203  if (y == 1)
204    p = "hello";
205
206  if (y == 1)
207    return p[0]; // no-warning
208    
209  return 'a';
210}
211
212// PR 3772
213// - We just want to test that this doesn't crash the analyzer.
214typedef struct st ST;
215struct st { char *name; };
216extern ST *Cur_Pu;
217
218void pr3772(void)
219{
220  static ST *last_Cur_Pu;
221  if (last_Cur_Pu == Cur_Pu) {
222    return;
223  } 
224}
225
226// PR 3780 - This tests that StmtIterator isn't broken for VLAs in DeclGroups.
227void pr3780(int sz) { typedef double MAT[sz][sz]; }
228
229// <rdar://problem/6695527> - Test that we don't symbolicate doubles before
230// we are ready to do something with them.
231int rdar6695527(double x) {
232  if (!x) { return 0; }
233  return 1;
234}
235
236// <rdar://problem/6708148> - Test that we properly invalidate structs
237//  passed-by-reference to a function.
238void pr6708148_invalidate(NSRect *x);
239void pr6708148_use(NSRect x);
240void pr6708148_test(void) {
241  NSRect x;
242  pr6708148_invalidate(&x);
243  pr6708148_use(x); // no-warning
244}
245
246// Handle both kinds of noreturn attributes for pruning paths.
247void rdar_6777003_noret() __attribute__((noreturn));
248void rdar_6777003_analyzer_noret() __attribute__((analyzer_noreturn));
249
250void rdar_6777003(int x) {
251  int *p = 0;
252  
253  if (x == 1) {
254    rdar_6777003_noret();
255    *p = 1; // no-warning;    
256  }
257  
258  if (x == 2) {
259    rdar_6777003_analyzer_noret();
260    *p = 1; // no-warning;
261  }
262  
263  *p = 1; // expected-warning{{Dereference of null pointer}}  
264}
265
266// For pointer arithmetic, --/++ should be treated as preserving non-nullness,
267// regardless of how well the underlying StoreManager reasons about pointer
268// arithmetic.
269// <rdar://problem/6777209>
270void rdar_6777209(char *p) {
271  if (p == 0)
272    return;
273  
274  ++p;
275  
276  // This branch should always be infeasible.
277  if (p == 0)
278    *p = 'c'; // no-warning
279}
280
281// PR 4033.  A symbolic 'void *' pointer can be used as the address for a
282// computed goto.
283typedef void *Opcode;
284Opcode pr_4033_getOpcode();
285void pr_4033(void) {
286next_opcode:
287  {
288    Opcode op = pr_4033_getOpcode();
289    if (op) goto *op;
290  }
291}
292
293// Test invalidating pointers-to-pointers with slightly different types.  This
294// example came from a recent false positive due to a regression where the
295// branch condition was falsely reported as being uninitialized.
296void invalidate_by_ref(char **x);
297int test_invalidate_by_ref() {
298  unsigned short y;
299  invalidate_by_ref((char**) &y);
300  if (y) // no-warning
301    return 1;
302  return 0;  
303}
304
305// Test for <rdar://problem/7027684>.  This just tests that the CFG is
306// constructed correctly.  Previously, the successor block of the entrance
307// was the block containing the merge for '?', which would trigger an
308// assertion failure.
309int rdar_7027684_aux();
310int rdar_7027684_aux_2() __attribute__((noreturn));
311void rdar_7027684(int x, int y) {
312  {}; // this empty compound statement is critical.
313  (rdar_7027684_aux() ? rdar_7027684_aux_2() : (void) 0);
314}
315
316// Test that we handle casts of string literals to arbitrary types.
317unsigned const char *string_literal_test1() {
318  return (const unsigned char*) "hello";
319}
320
321const float *string_literal_test2() {
322  return (const float*) "hello";
323}
324
325// Test that we handle casts *from* incomplete struct types.
326extern const struct _FooAssertStruct _cmd;
327void test_cast_from_incomplete_struct_aux(volatile const void *x);
328void test_cast_from_incomplete_struct() {
329  test_cast_from_incomplete_struct_aux(&_cmd);
330}
331
332// Test for <rdar://problem/7034511> 
333//  "ValueManager::makeIntVal(uint64_t X, QualType T) should return a 'Loc' 
334//   when 'T' is a pointer"
335//
336// Previously this case would crash.
337void test_rdar_7034511(NSArray *y) {
338  NSObject *x;
339  for (x in y) {}
340  if (x == ((void*) 0)) {}
341}
342
343// Handle casts of function pointers (CodeTextRegions) to arbitrary pointer
344// types. This was previously causing a crash in CastRegion.
345void handle_funcptr_voidptr_casts() {
346  void **ptr;
347  typedef void *PVOID;
348  typedef void *PCHAR;  
349  typedef long INT_PTR, *PINT_PTR;
350  typedef INT_PTR (*FARPROC)();
351  FARPROC handle_funcptr_voidptr_casts_aux();
352  PVOID handle_funcptr_voidptr_casts_aux_2(PVOID volatile *x);
353  PVOID handle_funcptr_voidptr_casts_aux_3(PCHAR volatile *x);  
354  
355  ptr = (void**) handle_funcptr_voidptr_casts_aux();
356  handle_funcptr_voidptr_casts_aux_2(ptr);
357  handle_funcptr_voidptr_casts_aux_3(ptr);
358}
359
360// RegionStore::Retrieve previously crashed on this example.  This example
361// was previously in the test file 'xfail_regionstore_wine_crash.c'.
362void testA() {
363  long x = 0;
364  char *y = (char *) &x;
365  if (!*y)
366    return;
367}
368
369// RegionStoreManager previously crashed on this example.  The problem is that
370// the value bound to the field of b->grue after the call to testB_aux is
371// a symbolic region.  The second '*__gruep__' involves performing a load
372// from a 'int*' that really is a 'void**'.  The loaded location must be
373// implicitly converted to an integer that wraps a location.  Previosly we would
374// get a crash here due to an assertion failure.
375typedef struct _BStruct { void *grue; } BStruct;
376void testB_aux(void *ptr);
377void testB(BStruct *b) {
378  {
379    int *__gruep__ = ((int *)&((b)->grue));
380    int __gruev__ = *__gruep__;
381    testB_aux(__gruep__);
382  }
383  {
384    int *__gruep__ = ((int *)&((b)->grue));
385    int __gruev__ = *__gruep__;
386    if (~0 != __gruev__) {}
387  }
388}
389
390void test_trivial_symbolic_comparison(int *x) {
391  int test_trivial_symbolic_comparison_aux();
392  int a = test_trivial_symbolic_comparison_aux();
393  int b = a;
394  if (a != b) {
395    int *p = 0;
396    *p = 0xDEADBEEF;     // no-warning
397  }
398  
399  a = a == 1;
400  b = b == 1;
401  if (a != b) {
402    int *p = 0;
403    *p = 0xDEADBEEF;     // no-warning
404  }
405}
406
407// Test for:
408//  <rdar://problem/7062158> false positive null dereference due to
409//   BasicStoreManager not tracking *static* globals
410//
411// This just tests the proper tracking of symbolic values for globals (both 
412// static and non-static).
413//
414static int* x_rdar_7062158;
415void rdar_7062158() {
416  int *current = x_rdar_7062158;
417  if (current == x_rdar_7062158)
418    return;
419    
420  int *p = 0;
421  *p = 0xDEADBEEF; // no-warning  
422}
423
424int* x_rdar_7062158_2;
425void rdar_7062158_2() {
426  int *current = x_rdar_7062158_2;
427  if (current == x_rdar_7062158_2)
428    return;
429    
430  int *p = 0;
431  *p = 0xDEADBEEF; // no-warning  
432}
433
434// This test reproduces a case for a crash when analyzing ClamAV using
435// RegionStoreManager (the crash doesn't exhibit in BasicStoreManager because
436// it isn't doing anything smart about arrays).  The problem is that on the
437// second line, 'p = &p[i]', p is assigned an ElementRegion whose index
438// is a 16-bit integer.  On the third line, a new ElementRegion is created
439// based on the previous region, but there the region uses a 32-bit integer,
440// resulting in a clash of values (an assertion failure at best).  We resolve
441// this problem by implicitly converting index values to 'int' when the
442// ElementRegion is created.
443unsigned char test_array_index_bitwidth(const unsigned char *p) {
444  unsigned short i = 0;
445  for (i = 0; i < 2; i++) p = &p[i];  
446  return p[i+1];
447}
448
449// This case tests that CastRegion handles casts involving BlockPointerTypes.
450// It should not crash.
451void test_block_cast() {
452  id test_block_cast_aux();
453  (void (^)(void *))test_block_cast_aux(); // expected-warning{{expression result unused}}
454}
455
456// Test comparison of 'id' instance variable to a null void* constant after
457// performing an OSAtomicCompareAndSwap32Barrier.
458// This previously was a crash in RegionStoreManager.
459@interface TestIdNull {
460  id x;
461}
462-(int)foo;
463@end
464@implementation TestIdNull
465-(int)foo {
466  OSAtomicCompareAndSwap32Barrier(0, (signed)2, (signed*)&x);  
467  if (x == (void*) 0) { return 0; }
468  return 1;
469}
470@end
471
472// PR 4594 - This was a crash when handling casts in SimpleSValuator.
473void PR4594() {
474  char *buf[1];
475  char **foo = buf;
476  *foo = "test";
477}
478
479// Test invalidation logic where an integer is casted to an array with a
480// different sign and then invalidated.
481void test_invalidate_cast_int() {
482  void test_invalidate_cast_int_aux(unsigned *i);
483  signed i;  
484  test_invalidate_cast_int_aux((unsigned*) &i);
485  if (i < 0)
486    return;
487}
488
489// Reduced from a crash involving the cast of an Objective-C symbolic region to
490// 'char *'
491static NSNumber *test_ivar_offset(id self, SEL _cmd, Ivar inIvar) {
492  return [[[NSNumber allocWithZone:((void*)0)] initWithBool:*(_Bool *)((char *)self + ivar_getOffset(inIvar))] autorelease];
493}
494
495// Reduced from a crash in StoreManager::CastRegion involving a divide-by-zero.
496// This resulted from not properly handling region casts to 'const void*'.
497void test_cast_const_voidptr() {
498  char x[10];
499  char *p = &x[1];
500  const void* q = p;
501}
502
503// Reduced from a crash when analyzing Wine.  This test handles loads from
504// function addresses.
505typedef long (*FARPROC)();
506FARPROC test_load_func(FARPROC origfun) {
507  if (!*(unsigned char*) origfun)
508    return origfun;
509  return 0;
510}
511