blob: e49cdb0a962d2e784f826e600e3c96d7ada9ff77 [file] [log] [blame]
Daniel Dunbard7d5f022009-03-24 02:24:46 +00001// RUN: clang-cc -analyze -checker-cfref --analyzer-store=basic -analyzer-constraints=basic --verify -fblocks %s &&
Ted Kremenek921109a2009-07-01 23:19:52 +00002// 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
Ted Kremenek2dabd422009-01-22 18:53:15 +00005
Ted Kremenekf684d562009-03-05 18:08:28 +00006typedef struct objc_selector *SEL;
7typedef signed char BOOL;
8typedef int NSInteger;
9typedef unsigned int NSUInteger;
10typedef struct _NSZone NSZone;
Ted Kremenek59978882009-07-08 22:42:46 +000011@class NSInvocation, NSArray, NSMethodSignature, NSCoder, NSString, NSEnumerator;
Ted Kremenekf684d562009-03-05 18:08:28 +000012@protocol NSObject - (BOOL)isEqual:(id)object; @end
13@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end
14@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end
15@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end
16@interface NSObject <NSObject> {} - (id)init; @end
17extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
18@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
19- (NSUInteger)length;
20+ (id)stringWithUTF8String:(const char *)nullTerminatedCString;
21@end extern NSString * const NSBundleDidLoadNotification;
22@interface NSAssertionHandler : NSObject {}
23+ (NSAssertionHandler *)currentHandler;
24- (void)handleFailureInMethod:(SEL)selector object:(id)object file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format,...;
25@end
26extern NSString * const NSConnectionReplyMode;
Ted Kremenek693de5d2009-03-23 15:42:58 +000027typedef float CGFloat;
28typedef struct _NSPoint {
29 CGFloat x;
30 CGFloat y;
31} NSPoint;
32typedef struct _NSSize {
33 CGFloat width;
34 CGFloat height;
35} NSSize;
36typedef struct _NSRect {
37 NSPoint origin;
38 NSSize size;
39} NSRect;
Ted Kremenek9f67ede2008-10-01 05:05:46 +000040
41// Reduced test case from crash in <rdar://problem/6253157>
Ted Kremenek9f67ede2008-10-01 05:05:46 +000042@interface A @end
43@implementation A
44- (void)foo:(void (^)(NSObject *x))block {
45 if (!((block != ((void *)0)))) {}
46}
47@end
48
Ted Kremenek6dfe2f52008-10-18 22:20:20 +000049// Reduced test case from crash in PR 2796;
50// http://llvm.org/bugs/show_bug.cgi?id=2796
51
52unsigned foo(unsigned x) { return __alignof__((x)) + sizeof(x); }
Ted Kremenek9253b0f2008-10-20 23:14:31 +000053
54// Improvement to path-sensitivity involving compound assignments.
55// Addresses false positive in <rdar://problem/6268365>
56//
57
58unsigned r6268365Aux();
59
60void r6268365() {
61 unsigned x = 0;
62 x &= r6268365Aux();
63 unsigned j = 0;
64
65 if (x == 0) ++j;
66 if (x == 0) x = x / j; // no-warning
67}
68
Ted Kremenekc13b6e22008-10-20 23:40:25 +000069void divzeroassume(unsigned x, unsigned j) {
70 x /= j;
71 if (j == 0) x /= 0; // no-warning
72 if (j == 0) x /= j; // no-warning
73 if (j == 0) x = x / 0; // no-warning
74}
75
76void divzeroassumeB(unsigned x, unsigned j) {
77 x = x / j;
78 if (j == 0) x /= 0; // no-warning
79 if (j == 0) x /= j; // no-warning
80 if (j == 0) x = x / 0; // no-warning
81}
82
Ted Kremenek76dba7b2008-11-13 05:05:34 +000083// InitListExpr processing
84
85typedef float __m128 __attribute__((__vector_size__(16), __may_alias__));
86__m128 return128() {
Ted Kremenek062e2f92008-11-13 06:10:40 +000087 // This compound literal has a Vector type. We currently just
88 // return UnknownVal.
Ted Kremenek76dba7b2008-11-13 05:05:34 +000089 return __extension__(__m128) { 0.0f, 0.0f, 0.0f, 0.0f };
90}
91
Ted Kremenek062e2f92008-11-13 06:10:40 +000092typedef long long __v2di __attribute__ ((__vector_size__ (16)));
93typedef long long __m128i __attribute__ ((__vector_size__ (16), __may_alias__));
94__m128i vec128i(long long __q1, long long __q0) {
95 // This compound literal returns true for both isVectorType() and
96 // isIntegerType().
97 return __extension__ (__m128i)(__v2di){ __q0, __q1 };
98}
99
Ted Kremenek8322d6a2008-12-09 00:14:48 +0000100// Zero-sized VLAs.
101void check_zero_sized_VLA(int x) {
102 if (x)
103 return;
104
Ted Kremenekeaedfea2009-05-10 05:11:21 +0000105 int vla[x]; // expected-warning{{Variable-length array 'vla' has zero elements (undefined behavior)}}
Ted Kremenek159d2482008-12-09 00:44:16 +0000106}
107
108void check_uninit_sized_VLA() {
109 int x;
Ted Kremenekeaedfea2009-05-10 05:11:21 +0000110 int vla[x]; // expected-warning{{Variable-length array 'vla' garbage value for array size}}
Ted Kremenek8322d6a2008-12-09 00:14:48 +0000111}
Ted Kremenek062e2f92008-11-13 06:10:40 +0000112
Ted Kremenek55f7bcb2008-12-15 18:51:00 +0000113// sizeof(void)
114// - Tests a regression reported in PR 3211: http://llvm.org/bugs/show_bug.cgi?id=3211
115void handle_sizeof_void(unsigned flag) {
116 int* p = 0;
117
118 if (flag) {
119 if (sizeof(void) == 1)
120 return;
121 // Infeasible.
122 *p = 1; // no-warning
123 }
124
125 void* q;
126
127 if (!flag) {
128 if (sizeof(*q) == 1)
129 return;
130 // Infeasibe.
131 *p = 1; // no-warning
132 }
133
134 // Infeasible.
135 *p = 1; // no-warning
136}
137
Ted Kremenekd76d47e2009-01-27 18:29:03 +0000138// PR 3422
139void pr3422_helper(char *p);
140void pr3422() {
141 char buf[100];
142 char *q = &buf[10];
143 pr3422_helper(&q[1]);
144}
145
Ted Kremeneka3d1eb82009-02-14 05:55:08 +0000146// PR 3543 (handle empty statement expressions)
Mike Stump006105d2009-07-21 18:59:16 +0000147void pr_3543(void) {
Ted Kremeneka3d1eb82009-02-14 05:55:08 +0000148 ({});
149}
150
Ted Kremenek265a3052009-02-24 02:23:11 +0000151// <rdar://problem/6611677>
152// This test case test the use of a vector type within an array subscript
153// expression.
154typedef long long __a64vector __attribute__((__vector_size__(8)));
155typedef long long __a128vector __attribute__((__vector_size__(16)));
156static inline __a64vector __attribute__((__always_inline__, __nodebug__))
157my_test_mm_movepi64_pi64(__a128vector a) {
158 return (__a64vector)a[0];
159}
160
Ted Kremenekf684d562009-03-05 18:08:28 +0000161// Test basic tracking of ivars associated with 'self'.
162@interface SelfIvarTest : NSObject {
163 int flag;
164}
165- (void)test_self_tracking;
166@end
167
168@implementation SelfIvarTest
169- (void)test_self_tracking {
170 char *p = 0;
171 char c;
172
173 if (flag)
174 p = "hello";
175
176 if (flag)
177 c = *p; // no-warning
178}
179@end
Ted Kremeneka3d1eb82009-02-14 05:55:08 +0000180
Ted Kremenek7de20fe2009-03-11 02:29:48 +0000181// PR 3770
182char pr3770(int x) {
183 int y = x & 0x2;
184 char *p = 0;
185 if (y == 1)
186 p = "hello";
187
188 if (y == 1)
189 return p[0]; // no-warning
190
191 return 'a';
192}
193
Ted Kremenek344d4c82009-03-11 18:17:16 +0000194// PR 3772
Ted Kremenekfa6228d2009-03-11 02:52:39 +0000195// - We just want to test that this doesn't crash the analyzer.
196typedef struct st ST;
197struct st { char *name; };
198extern ST *Cur_Pu;
199
Ted Kremenek344d4c82009-03-11 18:17:16 +0000200void pr3772(void)
Ted Kremenekfa6228d2009-03-11 02:52:39 +0000201{
202 static ST *last_Cur_Pu;
203 if (last_Cur_Pu == Cur_Pu) {
204 return;
205 }
206}
207
Ted Kremenek344d4c82009-03-11 18:17:16 +0000208// PR 3780 - This tests that StmtIterator isn't broken for VLAs in DeclGroups.
209void pr3780(int sz) { typedef double MAT[sz][sz]; }
Ted Kremenekfa6228d2009-03-11 02:52:39 +0000210
Ted Kremenekec099f12009-03-18 22:10:22 +0000211// <rdar://problem/6695527> - Test that we don't symbolicate doubles before
212// we are ready to do something with them.
213int rdar6695527(double x) {
214 if (!x) { return 0; }
215 return 1;
216}
Ted Kremenek693de5d2009-03-23 15:42:58 +0000217
218// <rdar://problem/6708148> - Test that we properly invalidate structs
219// passed-by-reference to a function.
220void pr6708148_invalidate(NSRect *x);
221void pr6708148_use(NSRect x);
222void pr6708148_test(void) {
223 NSRect x;
224 pr6708148_invalidate(&x);
225 pr6708148_use(x); // no-warning
226}
227
Ted Kremenekb7252322009-04-10 00:01:14 +0000228// Handle both kinds of noreturn attributes for pruning paths.
229void rdar_6777003_noret() __attribute__((noreturn));
230void rdar_6777003_analyzer_noret() __attribute__((analyzer_noreturn));
231
232void rdar_6777003(int x) {
233 int *p = 0;
234
235 if (x == 1) {
236 rdar_6777003_noret();
237 *p = 1; // no-warning;
238 }
239
240 if (x == 2) {
241 rdar_6777003_analyzer_noret();
242 *p = 1; // no-warning;
243 }
244
245 *p = 1; // expected-warning{{Dereference of null pointer}}
246}
247
Ted Kremenekaf48fdd2009-04-21 22:38:05 +0000248// For pointer arithmetic, --/++ should be treated as preserving non-nullness,
249// regardless of how well the underlying StoreManager reasons about pointer
250// arithmetic.
251// <rdar://problem/6777209>
Ted Kremenekaf48fdd2009-04-21 22:38:05 +0000252void rdar_6777209(char *p) {
253 if (p == 0)
254 return;
255
256 ++p;
257
258 // This branch should always be infeasible.
259 if (p == 0)
260 *p = 'c'; // no-warning
261}
Ted Kremenekb3cfd582009-04-23 17:49:43 +0000262
263// PR 4033. A symbolic 'void *' pointer can be used as the address for a
264// computed goto.
265typedef void *Opcode;
266Opcode pr_4033_getOpcode();
267void pr_4033(void) {
268next_opcode:
269 {
270 Opcode op = pr_4033_getOpcode();
271 if (op) goto *op;
272 }
273}
274
Ted Kremenek956a37d2009-05-01 23:35:18 +0000275// Test invalidating pointers-to-pointers with slightly different types. This
276// example came from a recent false positive due to a regression where the
277// branch condition was falsely reported as being uninitialized.
278void invalidate_by_ref(char **x);
279int test_invalidate_by_ref() {
280 unsigned short y;
281 invalidate_by_ref((char**) &y);
282 if (y) // no-warning
283 return 1;
284 return 0;
285}
286
Ted Kremeneked47fc62009-07-03 00:10:50 +0000287// Test for <rdar://problem/7027684>. This just tests that the CFG is
288// constructed correctly. Previously, the successor block of the entrance
289// was the block containing the merge for '?', which would trigger an
290// assertion failure.
291int rdar_7027684_aux();
292int rdar_7027684_aux_2() __attribute__((noreturn));
293void rdar_7027684(int x, int y) {
294 {}; // this empty compound statement is critical.
295 (rdar_7027684_aux() ? rdar_7027684_aux_2() : (void) 0);
296}
297
Ted Kremenek411af402009-07-06 22:23:45 +0000298// Test that we handle casts of string literals to arbitrary types.
299unsigned const char *string_literal_test1() {
300 return (const unsigned char*) "hello";
301}
302
303const float *string_literal_test2() {
304 return (const float*) "hello";
305}
306
Ted Kremenek169077d2009-07-06 23:47:19 +0000307// Test that we handle casts *from* incomplete struct types.
308extern const struct _FooAssertStruct _cmd;
309void test_cast_from_incomplete_struct_aux(volatile const void *x);
310void test_cast_from_incomplete_struct() {
311 test_cast_from_incomplete_struct_aux(&_cmd);
312}
Ted Kremeneked47fc62009-07-03 00:10:50 +0000313
Ted Kremenek59978882009-07-08 22:42:46 +0000314// Test for <rdar://problem/7034511>
315// "ValueManager::makeIntVal(uint64_t X, QualType T) should return a 'Loc'
316// when 'T' is a pointer"
317//
318// Previously this case would crash.
319void test_rdar_7034511(NSArray *y) {
320 NSObject *x;
321 for (x in y) {}
322 if (x == ((void*) 0)) {}
323}
324
Ted Kremenek8d344ae2009-07-10 21:24:45 +0000325// Handle casts of function pointers (CodeTextRegions) to arbitrary pointer
326// types. This was previously causing a crash in CastRegion.
327void handle_funcptr_voidptr_casts() {
Ted Kremenek3f9811b2009-07-10 21:11:16 +0000328 void **ptr;
329 typedef void *PVOID;
Ted Kremenek8d344ae2009-07-10 21:24:45 +0000330 typedef void *PCHAR;
Ted Kremenek3f9811b2009-07-10 21:11:16 +0000331 typedef long INT_PTR, *PINT_PTR;
332 typedef INT_PTR (*FARPROC)();
Ted Kremenek8d344ae2009-07-10 21:24:45 +0000333 FARPROC handle_funcptr_voidptr_casts_aux();
334 PVOID handle_funcptr_voidptr_casts_aux_2(PVOID volatile *x);
335 PVOID handle_funcptr_voidptr_casts_aux_3(PCHAR volatile *x);
Ted Kremenek3f9811b2009-07-10 21:11:16 +0000336
Ted Kremenek8d344ae2009-07-10 21:24:45 +0000337 ptr = (void**) handle_funcptr_voidptr_casts_aux();
338 handle_funcptr_voidptr_casts_aux_2(ptr);
339 handle_funcptr_voidptr_casts_aux_3(ptr);
Ted Kremenek3f9811b2009-07-10 21:11:16 +0000340}
341
Ted Kremenek31ef2b62009-07-10 21:43:30 +0000342// RegionStore::Retrieve previously crashed on this example. This example
343// was previously in the test file 'xfail_regionstore_wine_crash.c'.
344void testA() {
345 long x = 0;
346 char *y = (char *) &x;
347 if (!*y)
348 return;
349}
350
Ted Kremenek43d74a52009-07-11 04:38:49 +0000351// RegionStoreManager previously crashed on this example. The problem is that
352// the value bound to the field of b->grue after the call to testB_aux is
353// a symbolic region. The second '*__gruep__' involves performing a load
354// from a 'int*' that really is a 'void**'. The loaded location must be
355// implicitly converted to an integer that wraps a location. Previosly we would
356// get a crash here due to an assertion failure.
357typedef struct _BStruct { void *grue; } BStruct;
358void testB_aux(void *ptr);
359void testB(BStruct *b) {
360 {
361 int *__gruep__ = ((int *)&((b)->grue));
362 int __gruev__ = *__gruep__;
363 testB_aux(__gruep__);
364 }
365 {
366 int *__gruep__ = ((int *)&((b)->grue));
367 int __gruev__ = *__gruep__;
368 if (~0 != __gruev__) {}
369 }
370}
371
Ted Kremenek54ca9b12009-07-13 21:55:12 +0000372void test_trivial_symbolic_comparison(int *x) {
373 int test_trivial_symbolic_comparison_aux();
374 int a = test_trivial_symbolic_comparison_aux();
375 int b = a;
376 if (a != b) {
377 int *p = 0;
378 *p = 0xDEADBEEF; // no-warning
379 }
380
381 a = a == 1;
382 b = b == 1;
383 if (a != b) {
384 int *p = 0;
385 *p = 0xDEADBEEF; // no-warning
386 }
387}
388
Ted Kremenekfde2efe2009-07-15 22:09:25 +0000389// Test for:
390// <rdar://problem/7062158> false positive null dereference due to
391// BasicStoreManager not tracking *static* globals
392//
393// This just tests the proper tracking of symbolic values for globals (both
394// static and non-static).
395//
396static int* x_rdar_7062158;
397void rdar_7062158() {
398 int *current = x_rdar_7062158;
399 if (current == x_rdar_7062158)
400 return;
401
402 int *p = 0;
403 *p = 0xDEADBEEF; // no-warning
404}
405
406int* x_rdar_7062158_2;
407void rdar_7062158_2() {
408 int *current = x_rdar_7062158_2;
409 if (current == x_rdar_7062158_2)
410 return;
411
412 int *p = 0;
413 *p = 0xDEADBEEF; // no-warning
414}
415
Ted Kremenek46537392009-07-16 01:33:37 +0000416// This test reproduces a case for a crash when analyzing ClamAV using
417// RegionStoreManager (the crash doesn't exhibit in BasicStoreManager because
418// it isn't doing anything smart about arrays). The problem is that on the
419// second line, 'p = &p[i]', p is assigned an ElementRegion whose index
420// is a 16-bit integer. On the third line, a new ElementRegion is created
421// based on the previous region, but there the region uses a 32-bit integer,
422// resulting in a clash of values (an assertion failure at best). We resolve
423// this problem by implicitly converting index values to 'int' when the
424// ElementRegion is created.
425unsigned char test_array_index_bitwidth(const unsigned char *p) {
426 unsigned short i = 0;
427 for (i = 0; i < 2; i++) p = &p[i];
428 return p[i+1];
429}
430
Ted Kremenek63b9cfe2009-07-18 06:27:51 +0000431// This case tests that CastRegion handles casts involving BlockPointerTypes.
432// It should not crash.
433void test_block_cast() {
434 id test_block_cast_aux();
435 (void (^)(void *))test_block_cast_aux(); // expected-warning{{expression result unused}}
436}
437
Ted Kremenek293769a2009-07-20 21:00:55 +0000438// Test comparison of 'id' instance variable to a null void* constant after
439// performing an OSAtomicCompareAndSwap32Barrier.
440// This previously was a crash in RegionStoreManager.
441@interface TestIdNull {
442 id x;
443}
444-(int)foo;
445@end
446@implementation TestIdNull
447-(int)foo {
448 OSAtomicCompareAndSwap32Barrier(0, (signed)2, (signed*)&x);
449 if (x == (void*) 0) { return 0; }
450 return 1;
451}
452@end
453
Ted Kremenek32c3fa42009-07-21 21:03:30 +0000454// PR 4594 - This was a crash when handling casts in SimpleSValuator.
455void PR4594() {
456 char *buf[1];
457 char **foo = buf;
458 *foo = "test";
459}
Ted Kremenek0b331e32009-07-22 04:23:20 +0000460
461// Test invalidation logic where an integer is casted to an array with a
462// different sign and then invalidated.
463void test_invalidate_cast_int() {
464 void test_invalidate_cast_int_aux(unsigned *i);
465 signed i;
466 test_invalidate_cast_int_aux((unsigned*) &i);
467 if (i < 0)
468 return;
469}
470