1 | // NOTE: Use '-fobjc-gc' to test the analysis being run twice, and multiple reports are not issued. |
2 | // RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=core,alpha.core,osx.cocoa.AtSync -analyzer-store=region -verify -fblocks -Wno-unreachable-code -Wno-null-dereference -Wno-objc-root-class %s |
3 | // RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,alpha.core,osx.cocoa.AtSync -analyzer-store=region -verify -fblocks -Wno-unreachable-code -Wno-null-dereference -Wno-objc-root-class %s |
4 | |
5 | #ifndef __clang_analyzer__ |
6 | #error __clang_analyzer__ not defined |
7 | #endif |
8 | |
9 | typedef struct objc_ivar *Ivar; |
10 | typedef struct objc_selector *SEL; |
11 | typedef signed char BOOL; |
12 | typedef int NSInteger; |
13 | typedef unsigned int NSUInteger; |
14 | typedef struct _NSZone NSZone; |
15 | @class NSInvocation, NSArray, NSMethodSignature, NSCoder, NSString, NSEnumerator; |
16 | @protocol NSObject |
17 | - (BOOL)isEqual:(id)object; |
18 | - (id)autorelease; |
19 | @end |
20 | @protocol NSCopying |
21 | - (id)copyWithZone:(NSZone *)zone; |
22 | @end |
23 | @protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end |
24 | @protocol NSCoding |
25 | - (void)encodeWithCoder:(NSCoder *)aCoder; |
26 | @end |
27 | @interface NSObject <NSObject> {} |
28 | - (id)init; |
29 | + (id)allocWithZone:(NSZone *)zone; |
30 | @end |
31 | extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone); |
32 | @interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding> |
33 | - (NSUInteger)length; |
34 | + (id)stringWithUTF8String:(const char *)nullTerminatedCString; |
35 | @end extern NSString * const NSBundleDidLoadNotification; |
36 | @interface NSValue : NSObject <NSCopying, NSCoding> |
37 | - (void)getValue:(void *)value; |
38 | @end |
39 | @interface NSNumber : NSValue |
40 | - (char)charValue; |
41 | - (id)initWithBool:(BOOL)value; |
42 | @end |
43 | @interface NSAssertionHandler : NSObject {} |
44 | + (NSAssertionHandler *)currentHandler; |
45 | - (void)handleFailureInMethod:(SEL)selector object:(id)object file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format,...; |
46 | @end |
47 | extern NSString * const NSConnectionReplyMode; |
48 | typedef float CGFloat; |
49 | typedef struct _NSPoint { |
50 | CGFloat x; |
51 | CGFloat y; |
52 | } NSPoint; |
53 | typedef struct _NSSize { |
54 | CGFloat width; |
55 | CGFloat height; |
56 | } NSSize; |
57 | typedef struct _NSRect { |
58 | NSPoint origin; |
59 | NSSize size; |
60 | } NSRect; |
61 | |
62 | // Reduced test case from crash in <rdar://problem/6253157> |
63 | @interface A @end |
64 | @implementation A |
65 | - (void)foo:(void (^)(NSObject *x))block { |
66 | if (!((block != ((void *)0)))) {} |
67 | } |
68 | @end |
69 | |
70 | // Reduced test case from crash in PR 2796; |
71 | // http://llvm.org/bugs/show_bug.cgi?id=2796 |
72 | |
73 | unsigned foo(unsigned x) { return __alignof__((x)) + sizeof(x); } |
74 | |
75 | // Improvement to path-sensitivity involving compound assignments. |
76 | // Addresses false positive in <rdar://problem/6268365> |
77 | // |
78 | |
79 | unsigned r6268365Aux(); |
80 | |
81 | void r6268365() { |
82 | unsigned x = 0; |
83 | x &= r6268365Aux(); |
84 | unsigned j = 0; |
85 | |
86 | if (x == 0) ++j; |
87 | if (x == 0) x = x / j; |
88 | } |
89 | |
90 | void divzeroassume(unsigned x, unsigned j) { |
91 | x /= j; |
92 | if (j == 0) x /= 0; // no static-analyzer warning expected-warning {{division by zero is undefined}} |
93 | if (j == 0) x /= j; // no static-analyzer warning |
94 | if (j == 0) x = x / 0; // no static-analyzer warning expected-warning {{division by zero is undefined}} |
95 | } |
96 | |
97 | void divzeroassumeB(unsigned x, unsigned j) { |
98 | x = x / j; |
99 | if (j == 0) x /= 0; // no static-analyzer warning expected-warning {{division by zero is undefined}} |
100 | if (j == 0) x /= j; // no static-analyzer warning |
101 | if (j == 0) x = x / 0; // no static-analyzer warning expected-warning {{division by zero is undefined}} |
102 | } |
103 | |
104 | // InitListExpr processing |
105 | |
106 | typedef float __m128 __attribute__((__vector_size__(16), __may_alias__)); |
107 | __m128 return128() { |
108 | // This compound literal has a Vector type. We currently just |
109 | // return UnknownVal. |
110 | return __extension__(__m128) { 0.0f, 0.0f, 0.0f, 0.0f }; |
111 | } |
112 | |
113 | typedef long long __v2di __attribute__ ((__vector_size__ (16))); |
114 | typedef long long __m128i __attribute__ ((__vector_size__ (16), __may_alias__)); |
115 | __m128i vec128i(long long __q1, long long __q0) { |
116 | // This compound literal returns true for both isVectorType() and |
117 | // isIntegerType(). |
118 | return __extension__ (__m128i)(__v2di){ __q0, __q1 }; |
119 | } |
120 | |
121 | // sizeof(void) |
122 | // - Tests a regression reported in PR 3211: http://llvm.org/bugs/show_bug.cgi?id=3211 |
123 | void handle_sizeof_void(unsigned flag) { |
124 | int* p = 0; |
125 | |
126 | if (flag) { |
127 | if (sizeof(void) == 1) |
128 | return; |
129 | // Infeasible. |
130 | *p = 1; // no-warning |
131 | } |
132 | |
133 | void* q; |
134 | |
135 | if (!flag) { |
136 | if (sizeof(*q) == 1) |
137 | return; |
138 | // Infeasibe. |
139 | *p = 1; // no-warning |
140 | } |
141 | |
142 | // Infeasible. |
143 | *p = 1; // no-warning |
144 | } |
145 | |
146 | // check deference of undefined values |
147 | void check_deref_undef(void) { |
148 | int *p; |
149 | *p = 0xDEADBEEF; // expected-warning{{Dereference of undefined pointer value}} |
150 | } |
151 | |
152 | // PR 3422 |
153 | void pr3422_helper(char *p); |
154 | void pr3422() { |
155 | char buf[100]; |
156 | char *q = &buf[10]; |
157 | pr3422_helper(&q[1]); |
158 | } |
159 | |
160 | // PR 3543 (handle empty statement expressions) |
161 | void pr_3543(void) { |
162 | ({}); |
163 | } |
164 | |
165 | // <rdar://problem/6611677> |
166 | // This test case test the use of a vector type within an array subscript |
167 | // expression. |
168 | typedef long long __a64vector __attribute__((__vector_size__(8))); |
169 | typedef long long __a128vector __attribute__((__vector_size__(16))); |
170 | static inline __a64vector __attribute__((__always_inline__, __nodebug__)) |
171 | my_test_mm_movepi64_pi64(__a128vector a) { |
172 | return (__a64vector)a[0]; |
173 | } |
174 | |
175 | // Test basic tracking of ivars associated with 'self'. |
176 | @interface SelfIvarTest : NSObject { |
177 | int flag; |
178 | } |
179 | - (void)test_self_tracking; |
180 | @end |
181 | |
182 | @implementation SelfIvarTest |
183 | - (void)test_self_tracking { |
184 | char *p = 0; |
185 | char c; |
186 | |
187 | if (flag) |
188 | p = "hello"; |
189 | |
190 | if (flag) |
191 | c = *p; // no-warning |
192 | } |
193 | @end |
194 | |
195 | // PR 3770 |
196 | char pr3770(int x) { |
197 | int y = x & 0x2; |
198 | char *p = 0; |
199 | if (y == 1) |
200 | p = "hello"; |
201 | |
202 | if (y == 1) |
203 | return p[0]; // no-warning |
204 | |
205 | return 'a'; |
206 | } |
207 | |
208 | // PR 3772 |
209 | // - We just want to test that this doesn't crash the analyzer. |
210 | typedef struct st ST; |
211 | struct st { char *name; }; |
212 | extern ST *Cur_Pu; |
213 | |
214 | void pr3772(void) |
215 | { |
216 | static ST *last_Cur_Pu; |
217 | if (last_Cur_Pu == Cur_Pu) { |
218 | return; |
219 | } |
220 | } |
221 | |
222 | // PR 3780 - This tests that StmtIterator isn't broken for VLAs in DeclGroups. |
223 | void pr3780(int sz) { typedef double MAT[sz][sz]; } |
224 | |
225 | // <rdar://problem/6695527> - Test that we don't symbolicate doubles before |
226 | // we are ready to do something with them. |
227 | int rdar6695527(double x) { |
228 | if (!x) { return 0; } |
229 | return 1; |
230 | } |
231 | |
232 | // <rdar://problem/6708148> - Test that we properly invalidate structs |
233 | // passed-by-reference to a function. |
234 | void pr6708148_invalidate(NSRect *x); |
235 | void pr6708148_use(NSRect x); |
236 | void pr6708148_test(void) { |
237 | NSRect x; |
238 | pr6708148_invalidate(&x); |
239 | pr6708148_use(x); // no-warning |
240 | } |
241 | |
242 | // Handle both kinds of noreturn attributes for pruning paths. |
243 | void rdar_6777003_noret() __attribute__((noreturn)); |
244 | void rdar_6777003_analyzer_noret() __attribute__((analyzer_noreturn)); |
245 | |
246 | void rdar_6777003(int x) { |
247 | int *p = 0; |
248 | |
249 | if (x == 1) { |
250 | rdar_6777003_noret(); |
251 | *p = 1; // no-warning; |
252 | } |
253 | |
254 | if (x == 2) { |
255 | rdar_6777003_analyzer_noret(); |
256 | *p = 1; // no-warning; |
257 | } |
258 | |
259 | *p = 1; // expected-warning{{Dereference of null pointer}} |
260 | } |
261 | |
262 | // Check that the pointer-to-conts arguments do not get invalidated by Obj C |
263 | // interfaces. radar://10595327 |
264 | int rdar_10595327(char *str) { |
265 | char fl = str[0]; |
266 | int *p = 0; |
267 | NSString *s = [NSString stringWithUTF8String:str]; |
268 | if (str[0] != fl) |
269 | return *p; // no-warning |
270 | return 0; |
271 | } |
272 | |
273 | // For pointer arithmetic, --/++ should be treated as preserving non-nullness, |
274 | // regardless of how well the underlying StoreManager reasons about pointer |
275 | // arithmetic. |
276 | // <rdar://problem/6777209> |
277 | void rdar_6777209(char *p) { |
278 | if (p == 0) |
279 | return; |
280 | |
281 | ++p; |
282 | |
283 | // This branch should always be infeasible. |
284 | if (p == 0) |
285 | *p = 'c'; // no-warning |
286 | } |
287 | |
288 | // PR 4033. A symbolic 'void *' pointer can be used as the address for a |
289 | // computed goto. |
290 | typedef void *Opcode; |
291 | Opcode pr_4033_getOpcode(); |
292 | void pr_4033(void) { |
293 | void *lbl = &&next_opcode; |
294 | next_opcode: |
295 | { |
296 | Opcode op = pr_4033_getOpcode(); |
297 | if (op) goto *op; |
298 | } |
299 | } |
300 | |
301 | // Test invalidating pointers-to-pointers with slightly different types. This |
302 | // example came from a recent false positive due to a regression where the |
303 | // branch condition was falsely reported as being uninitialized. |
304 | void invalidate_by_ref(char **x); |
305 | int test_invalidate_by_ref() { |
306 | unsigned short y; |
307 | invalidate_by_ref((char**) &y); |
308 | if (y) // no-warning |
309 | return 1; |
310 | return 0; |
311 | } |
312 | |
313 | // Test for <rdar://problem/7027684>. This just tests that the CFG is |
314 | // constructed correctly. Previously, the successor block of the entrance |
315 | // was the block containing the merge for '?', which would trigger an |
316 | // assertion failure. |
317 | int rdar_7027684_aux(); |
318 | int rdar_7027684_aux_2() __attribute__((noreturn)); |
319 | void rdar_7027684(int x, int y) { |
320 | {}; // this empty compound statement is critical. |
321 | (rdar_7027684_aux() ? rdar_7027684_aux_2() : (void) 0); |
322 | } |
323 | |
324 | // Test that we handle casts of string literals to arbitrary types. |
325 | unsigned const char *string_literal_test1() { |
326 | return (const unsigned char*) "hello"; |
327 | } |
328 | |
329 | const float *string_literal_test2() { |
330 | return (const float*) "hello"; |
331 | } |
332 | |
333 | // Test that we handle casts *from* incomplete struct types. |
334 | extern const struct _FooAssertStruct _cmd; |
335 | void test_cast_from_incomplete_struct_aux(volatile const void *x); |
336 | void test_cast_from_incomplete_struct() { |
337 | test_cast_from_incomplete_struct_aux(&_cmd); |
338 | } |
339 | |
340 | // Test for <rdar://problem/7034511> |
341 | // "ValueManager::makeIntVal(uint64_t X, QualType T) should return a 'Loc' |
342 | // when 'T' is a pointer" |
343 | // |
344 | // Previously this case would crash. |
345 | void test_rdar_7034511(NSArray *y) { |
346 | NSObject *x; |
347 | for (x in y) {} |
348 | if (x == ((void*) 0)) {} |
349 | } |
350 | |
351 | // Handle casts of function pointers (CodeTextRegions) to arbitrary pointer |
352 | // types. This was previously causing a crash in CastRegion. |
353 | void handle_funcptr_voidptr_casts() { |
354 | void **ptr; |
355 | typedef void *PVOID; |
356 | typedef void *PCHAR; |
357 | typedef long INT_PTR, *PINT_PTR; |
358 | typedef INT_PTR (*FARPROC)(); |
359 | FARPROC handle_funcptr_voidptr_casts_aux(); |
360 | PVOID handle_funcptr_voidptr_casts_aux_2(PVOID volatile *x); |
361 | PVOID handle_funcptr_voidptr_casts_aux_3(PCHAR volatile *x); |
362 | |
363 | ptr = (void**) handle_funcptr_voidptr_casts_aux(); |
364 | handle_funcptr_voidptr_casts_aux_2(ptr); |
365 | handle_funcptr_voidptr_casts_aux_3(ptr); |
366 | } |
367 | |
368 | // RegionStore::Retrieve previously crashed on this example. This example |
369 | // was previously in the test file 'xfail_regionstore_wine_crash.c'. |
370 | void testA() { |
371 | long x = 0; |
372 | char *y = (char *) &x; |
373 | if (!*y) |
374 | return; |
375 | } |
376 | |
377 | // RegionStoreManager previously crashed on this example. The problem is that |
378 | // the value bound to the field of b->grue after the call to testB_aux is |
379 | // a symbolic region. The second '*__gruep__' involves performing a load |
380 | // from a 'int*' that really is a 'void**'. The loaded location must be |
381 | // implicitly converted to an integer that wraps a location. Previosly we would |
382 | // get a crash here due to an assertion failure. |
383 | typedef struct _BStruct { void *grue; } BStruct; |
384 | void testB_aux(void *ptr); |
385 | void testB(BStruct *b) { |
386 | { |
387 | int *__gruep__ = ((int *)&((b)->grue)); |
388 | int __gruev__ = *__gruep__; |
389 | testB_aux(__gruep__); |
390 | } |
391 | { |
392 | int *__gruep__ = ((int *)&((b)->grue)); |
393 | int __gruev__ = *__gruep__; |
394 | if (~0 != __gruev__) {} |
395 | } |
396 | } |
397 | |
398 | void test_trivial_symbolic_comparison(int *x) { |
399 | int test_trivial_symbolic_comparison_aux(); |
400 | int a = test_trivial_symbolic_comparison_aux(); |
401 | int b = a; |
402 | if (a != b) { |
403 | int *p = 0; |
404 | *p = 0xDEADBEEF; // no-warning |
405 | } |
406 | |
407 | a = a == 1; |
408 | b = b == 1; |
409 | if (a != b) { |
410 | int *p = 0; |
411 | *p = 0xDEADBEEF; // no-warning |
412 | } |
413 | } |
414 | |
415 | // Test for: |
416 | // <rdar://problem/7062158> false positive null dereference due to |
417 | // BasicStoreManager not tracking *static* globals |
418 | // |
419 | // This just tests the proper tracking of symbolic values for globals (both |
420 | // static and non-static). |
421 | // |
422 | static int* x_rdar_7062158; |
423 | void rdar_7062158() { |
424 | int *current = x_rdar_7062158; |
425 | if (current == x_rdar_7062158) |
426 | return; |
427 | |
428 | int *p = 0; |
429 | *p = 0xDEADBEEF; // no-warning |
430 | } |
431 | |
432 | int* x_rdar_7062158_2; |
433 | void rdar_7062158_2() { |
434 | int *current = x_rdar_7062158_2; |
435 | if (current == x_rdar_7062158_2) |
436 | return; |
437 | |
438 | int *p = 0; |
439 | *p = 0xDEADBEEF; // no-warning |
440 | } |
441 | |
442 | // This test reproduces a case for a crash when analyzing ClamAV using |
443 | // RegionStoreManager (the crash doesn't exhibit in BasicStoreManager because |
444 | // it isn't doing anything smart about arrays). The problem is that on the |
445 | // second line, 'p = &p[i]', p is assigned an ElementRegion whose index |
446 | // is a 16-bit integer. On the third line, a new ElementRegion is created |
447 | // based on the previous region, but there the region uses a 32-bit integer, |
448 | // resulting in a clash of values (an assertion failure at best). We resolve |
449 | // this problem by implicitly converting index values to 'int' when the |
450 | // ElementRegion is created. |
451 | unsigned char test_array_index_bitwidth(const unsigned char *p) { |
452 | unsigned short i = 0; |
453 | for (i = 0; i < 2; i++) p = &p[i]; |
454 | return p[i+1]; |
455 | } |
456 | |
457 | // This case tests that CastRegion handles casts involving BlockPointerTypes. |
458 | // It should not crash. |
459 | void test_block_cast() { |
460 | id test_block_cast_aux(); |
461 | (void (^)(void *))test_block_cast_aux(); // expected-warning{{expression result unused}} |
462 | } |
463 | |
464 | int OSAtomicCompareAndSwap32Barrier(); |
465 | |
466 | // Test comparison of 'id' instance variable to a null void* constant after |
467 | // performing an OSAtomicCompareAndSwap32Barrier. |
468 | // This previously was a crash in RegionStoreManager. |
469 | @interface TestIdNull { |
470 | id x; |
471 | } |
472 | -(int)foo; |
473 | @end |
474 | @implementation TestIdNull |
475 | -(int)foo { |
476 | OSAtomicCompareAndSwap32Barrier(0, (signed)2, (signed*)&x); |
477 | if (x == (void*) 0) { return 0; } |
478 | return 1; |
479 | } |
480 | @end |
481 | |
482 | // Do not crash when performing compare and swap on symbolic values. |
483 | typedef int int32_t; |
484 | typedef int int32; |
485 | typedef int32 Atomic32; |
486 | int OSAtomicCompareAndSwap32( int32_t __oldValue, int32_t __newValue, volatile int32_t *__theValue); |
487 | void radar11390991_NoBarrier_CompareAndSwap(volatile Atomic32 *ptr, |
488 | Atomic32 old_value, |
489 | Atomic32 new_value) { |
490 | OSAtomicCompareAndSwap32(old_value, new_value, ptr); |
491 | } |
492 | |
493 | // PR 4594 - This was a crash when handling casts in SimpleSValuator. |
494 | void PR4594() { |
495 | char *buf[1]; |
496 | char **foo = buf; |
497 | *foo = "test"; |
498 | } |
499 | |
500 | // Test invalidation logic where an integer is casted to an array with a |
501 | // different sign and then invalidated. |
502 | void test_invalidate_cast_int() { |
503 | void test_invalidate_cast_int_aux(unsigned *i); |
504 | signed i; |
505 | test_invalidate_cast_int_aux((unsigned*) &i); |
506 | if (i < 0) |
507 | return; |
508 | } |
509 | |
510 | int ivar_getOffset(); |
511 | |
512 | // Reduced from a crash involving the cast of an Objective-C symbolic region to |
513 | // 'char *' |
514 | static NSNumber *test_ivar_offset(id self, SEL _cmd, Ivar inIvar) { |
515 | return [[[NSNumber allocWithZone:((void*)0)] initWithBool:*(_Bool *)((char *)self + ivar_getOffset(inIvar))] autorelease]; |
516 | } |
517 | |
518 | // Reduced from a crash in StoreManager::CastRegion involving a divide-by-zero. |
519 | // This resulted from not properly handling region casts to 'const void*'. |
520 | void test_cast_const_voidptr() { |
521 | char x[10]; |
522 | char *p = &x[1]; |
523 | const void* q = p; |
524 | } |
525 | |
526 | // Reduced from a crash when analyzing Wine. This test handles loads from |
527 | // function addresses. |
528 | typedef long (*FARPROC)(); |
529 | FARPROC test_load_func(FARPROC origfun) { |
530 | if (!*(unsigned char*) origfun) |
531 | return origfun; |
532 | return 0; |
533 | } |
534 | |
535 | // Test passing-by-value an initialized struct variable. |
536 | struct test_pass_val { |
537 | int x; |
538 | int y; |
539 | }; |
540 | void test_pass_val_aux(struct test_pass_val s); |
541 | void test_pass_val() { |
542 | struct test_pass_val s; |
543 | s.x = 1; |
544 | s.y = 2; |
545 | test_pass_val_aux(s); |
546 | } |
547 | |
548 | // This is a reduced test case of a false positive that previously appeared |
549 | // in RegionStoreManager. Previously the array access resulted in dereferencing |
550 | // an undefined value. |
551 | int test_array_compound(int *q, int *r, int *z) { |
552 | int *array[] = { q, r, z }; |
553 | int j = 0; |
554 | for (unsigned i = 0; i < 3 ; ++i) |
555 | if (*array[i]) ++j; // no-warning |
556 | return j; |
557 | } |
558 | |
559 | // symbolic value stored in 'x' wouldn't be implicitly casted to a signed value |
560 | // during the comparison. |
561 | int rdar_7124210(unsigned int x) { |
562 | enum { SOME_CONSTANT = 123 }; |
563 | int compare = ((signed) SOME_CONSTANT) == *((signed *) &x); |
564 | return compare ? 0 : 1; // Forces the evaluation of the symbolic constraint. |
565 | } |
566 | |
567 | void pr4781(unsigned long *raw1) { |
568 | unsigned long *cook, *raw0; |
569 | unsigned long dough[32]; |
570 | int i; |
571 | cook = dough; |
572 | for( i = 0; i < 16; i++, raw1++ ) { |
573 | raw0 = raw1++; |
574 | *cook = (*raw0 & 0x00fc0000L) << 6; |
575 | *cook |= (*raw0 & 0x00000fc0L) << 10; |
576 | } |
577 | } |
578 | |
579 | // <rdar://problem/7185647> - 'self' should be treated as being non-null |
580 | // upon entry to an objective-c method. |
581 | @interface RDar7185647 |
582 | - (id)foo; |
583 | @end |
584 | @implementation RDar7185647 |
585 | - (id) foo { |
586 | if (self) |
587 | return self; |
588 | *((volatile int *) 0x0) = 0xDEADBEEF; // no-warning |
589 | return self; |
590 | } |
591 | @end |
592 | |
593 | // Test reasoning of __builtin_offsetof; |
594 | struct test_offsetof_A { |
595 | int x; |
596 | int y; |
597 | }; |
598 | struct test_offsetof_B { |
599 | int w; |
600 | int z; |
601 | }; |
602 | void test_offsetof_1() { |
603 | if (__builtin_offsetof(struct test_offsetof_A, x) == |
604 | __builtin_offsetof(struct test_offsetof_B, w)) |
605 | return; |
606 | int *p = 0; |
607 | *p = 0xDEADBEEF; // no-warning |
608 | } |
609 | void test_offsetof_2() { |
610 | if (__builtin_offsetof(struct test_offsetof_A, y) == |
611 | __builtin_offsetof(struct test_offsetof_B, z)) |
612 | return; |
613 | int *p = 0; |
614 | *p = 0xDEADBEEF; // no-warning |
615 | } |
616 | void test_offsetof_3() { |
617 | if (__builtin_offsetof(struct test_offsetof_A, y) - |
618 | __builtin_offsetof(struct test_offsetof_A, x) |
619 | == |
620 | __builtin_offsetof(struct test_offsetof_B, z) - |
621 | __builtin_offsetof(struct test_offsetof_B, w)) |
622 | return; |
623 | int *p = 0; |
624 | *p = 0xDEADBEEF; // no-warning |
625 | } |
626 | void test_offsetof_4() { |
627 | if (__builtin_offsetof(struct test_offsetof_A, y) == |
628 | __builtin_offsetof(struct test_offsetof_B, w)) |
629 | return; |
630 | int *p = 0; |
631 | *p = 0xDEADBEEF; // expected-warning{{Dereference of null pointer}} |
632 | } |
633 | |
634 | // <rdar://problem/6829164> "nil receiver" false positive: make tracking |
635 | // of the MemRegion for 'self' path-sensitive |
636 | @interface RDar6829164 : NSObject { |
637 | double x; int y; |
638 | } |
639 | - (id) init; |
640 | @end |
641 | |
642 | id rdar_6829164_1(); |
643 | double rdar_6829164_2(); |
644 | |
645 | @implementation RDar6829164 |
646 | - (id) init { |
647 | if((self = [super init]) != 0) { |
648 | id z = rdar_6829164_1(); |
649 | y = (z != 0); |
650 | if (y) |
651 | x = rdar_6829164_2(); |
652 | } |
653 | return self; |
654 | } |
655 | @end |
656 | |
657 | // <rdar://problem/7242015> - Invalidate values passed-by-reference |
658 | // to functions when the pointer to the value is passed as an integer. |
659 | void test_7242015_aux(unsigned long); |
660 | int rdar_7242015() { |
661 | int x; |
662 | test_7242015_aux((unsigned long) &x); // no-warning |
663 | return x; // Previously we return and uninitialized value when |
664 | // using RegionStore. |
665 | } |
666 | |
667 | // <rdar://problem/7242006> [RegionStore] compound literal assignment with |
668 | // floats not honored |
669 | CGFloat rdar7242006(CGFloat x) { |
670 | NSSize y = (NSSize){x, 10}; |
671 | return y.width; // no-warning |
672 | } |
673 | |
674 | // PR 4988 - This test exhibits a case where a function can be referenced |
675 | // when not explicitly used in an "lvalue" context (as far as the analyzer is |
676 | // concerned). This previously triggered a crash due to an invalid assertion. |
677 | void pr_4988(void) { |
678 | pr_4988; // expected-warning{{expression result unused}} |
679 | } |
680 | |
681 | // <rdar://problem/7152418> - A 'signed char' is used as a flag, which is |
682 | // implicitly converted to an int. |
683 | void *rdar7152418_bar(); |
684 | @interface RDar7152418 { |
685 | signed char x; |
686 | } |
687 | -(char)foo; |
688 | @end; |
689 | @implementation RDar7152418 |
690 | -(char)foo { |
691 | char *p = 0; |
692 | void *result = 0; |
693 | if (x) { |
694 | result = rdar7152418_bar(); |
695 | p = "hello"; |
696 | } |
697 | if (!result) { |
698 | result = rdar7152418_bar(); |
699 | if (result && x) |
700 | return *p; // no-warning |
701 | } |
702 | return 1; |
703 | } |
704 | |
705 | //===----------------------------------------------------------------------===// |
706 | // Test constant-folding of symbolic values, automatically handling type |
707 | // conversions of the symbol as necessary. |
708 | //===----------------------------------------------------------------------===// |
709 | |
710 | // Previously this would crash once we started eagerly evaluating symbols whose |
711 | // values were constrained to a single value. |
712 | void test_symbol_fold_1(signed char x) { |
713 | while (1) { |
714 | if (x == ((signed char) 0)) {} |
715 | } |
716 | } |
717 | |
718 | // This previously caused a crash because it triggered an assertion in APSInt. |
719 | void test_symbol_fold_2(unsigned int * p, unsigned int n, |
720 | const unsigned int * grumpkin, unsigned int dn) { |
721 | unsigned int i; |
722 | unsigned int tempsub[8]; |
723 | unsigned int *solgrumpkin = tempsub + n; |
724 | for (i = 0; i < n; i++) |
725 | solgrumpkin[i] = (i < dn) ? ~grumpkin[i] : 0xFFFFFFFF; |
726 | for (i <<= 5; i < (n << 5); i++) {} |
727 | } |
728 | |
729 | // This previously caused a crash because it triggered an assertion in APSInt. |
730 | // 'x' would evaluate to a 8-bit constant (because of the return value of |
731 | // test_symbol_fold_3_aux()) which would not get properly promoted to an |
732 | // integer. |
733 | char test_symbol_fold_3_aux(void); |
734 | unsigned test_symbol_fold_3(void) { |
735 | unsigned x = test_symbol_fold_3_aux(); |
736 | if (x == 54) |
737 | return (x << 8) | 0x5; |
738 | return 0; |
739 | } |
740 | |
741 | //===----------------------------------------------------------------------===// |
742 | // Tests for the warning of casting a non-struct type to a struct type |
743 | //===----------------------------------------------------------------------===// |
744 | |
745 | typedef struct {unsigned int v;} NSSwappedFloat; |
746 | |
747 | NSSwappedFloat test_cast_nonstruct_to_struct(float x) { |
748 | struct hodor { |
749 | float number; |
750 | NSSwappedFloat sf; |
751 | }; |
752 | return ((struct hodor *)&x)->sf; // expected-warning{{Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption}} |
753 | } |
754 | |
755 | NSSwappedFloat test_cast_nonstruct_to_union(float x) { |
756 | union bran { |
757 | float number; |
758 | NSSwappedFloat sf; |
759 | }; |
760 | return ((union bran *)&x)->sf; // no-warning |
761 | } |
762 | |
763 | void test_undefined_array_subscript() { |
764 | int i, a[10]; |
765 | int *p = &a[i]; // expected-warning{{Array subscript is undefined}} |
766 | } |
767 | @end |
768 | |
769 | //===----------------------------------------------------------------------===// |
770 | // Test using an uninitialized value as a branch condition. |
771 | //===----------------------------------------------------------------------===// |
772 | |
773 | int test_uninit_branch(void) { |
774 | int x; |
775 | if (x) // expected-warning{{Branch condition evaluates to a garbage value}} |
776 | return 1; |
777 | return 0; |
778 | } |
779 | |
780 | int test_uninit_branch_b(void) { |
781 | int x; |
782 | return x ? 1 : 0; // expected-warning{{Branch condition evaluates to a garbage value}} |
783 | } |
784 | |
785 | int test_uninit_branch_c(void) { |
786 | int x; |
787 | if ((short)x) // expected-warning{{Branch condition evaluates to a garbage value}} |
788 | return 1; |
789 | return 0; |
790 | } |
791 | |
792 | //===----------------------------------------------------------------------===// |
793 | // Test passing an undefined value in a message or function call. |
794 | //===----------------------------------------------------------------------===// |
795 | |
796 | void test_bad_call_aux(int x); |
797 | void test_bad_call(void) { |
798 | int y; |
799 | test_bad_call_aux(y); // expected-warning{{1st function call argument is an uninitialized value}} |
800 | } |
801 | |
802 | @interface TestBadArg {} |
803 | - (void) testBadArg:(int) x; |
804 | @end |
805 | |
806 | void test_bad_msg(TestBadArg *p) { |
807 | int y; |
808 | [p testBadArg:y]; // expected-warning{{1st argument in message expression is an uninitialized value}} |
809 | } |
810 | |
811 | //===----------------------------------------------------------------------===// |
812 | // PR 6033 - Test emitting the correct output in a warning where we use '%' |
813 | // with operands that are undefined. |
814 | //===----------------------------------------------------------------------===// |
815 | |
816 | int pr6033(int x) { |
817 | int y; |
818 | return x % y; // expected-warning{{The right operand of '%' is a garbage value}} |
819 | } |
820 | |
821 | struct trie { |
822 | struct trie* next; |
823 | }; |
824 | |
825 | struct kwset { |
826 | struct trie *trie; |
827 | unsigned char y[10]; |
828 | struct trie* next[10]; |
829 | int d; |
830 | }; |
831 | |
832 | typedef struct trie trie_t; |
833 | typedef struct kwset kwset_t; |
834 | |
835 | void f(kwset_t *kws, char const *p, char const *q) { |
836 | struct trie const *trie; |
837 | struct trie * const *next = kws->next; |
838 | register unsigned char c; |
839 | register char const *end = p; |
840 | register char const *lim = q; |
841 | register int d = 1; |
842 | register unsigned char const *y = kws->y; |
843 | |
844 | d = y[c = (end+=d)[-1]]; // no-warning |
845 | trie = next[c]; |
846 | } |
847 | |
848 | //===----------------------------------------------------------------------===// |
849 | // <rdar://problem/7593875> When handling sizeof(VLA) it leads to a hole in |
850 | // the ExplodedGraph (causing a false positive) |
851 | //===----------------------------------------------------------------------===// |
852 | |
853 | int rdar_7593875_aux(int x); |
854 | int rdar_7593875(int n) { |
855 | int z[n > 10 ? 10 : n]; // VLA. |
856 | int v; |
857 | v = rdar_7593875_aux(sizeof(z)); |
858 | // Previously we got a false positive about 'v' being uninitialized. |
859 | return v; // no-warning |
860 | } |
861 | |
862 | //===----------------------------------------------------------------------===// |
863 | // Handle casts from symbolic regions (packaged as integers) to doubles. |
864 | // Previously this caused an assertion failure. |
865 | //===----------------------------------------------------------------------===// |
866 | |
867 | void *foo_rev95119(); |
868 | void baz_rev95119(double x); |
869 | void bar_rev95119() { |
870 | // foo_rev95119() returns a symbolic pointer. It is then |
871 | // cast to an int which is then cast to a double. |
872 | int value = (int) foo_rev95119(); |
873 | baz_rev95119((double)value); |
874 | } |
875 | |
876 | //===----------------------------------------------------------------------===// |
877 | // Handle loading a symbolic pointer from a symbolic region that was |
878 | // invalidated by a call to an unknown function. |
879 | //===----------------------------------------------------------------------===// |
880 | |
881 | void bar_rev95192(int **x); |
882 | void foo_rev95192(int **x) { |
883 | *x = 0; |
884 | bar_rev95192(x); |
885 | // Not a null dereference. |
886 | **x = 1; // no-warning |
887 | } |
888 | |
889 | //===----------------------------------------------------------------------===// |
890 | // Handle casts of a function to a function pointer with a different return |
891 | // value. We don't yet emit an error for such cases, but we now we at least |
892 | // don't crash when the return value gets interpreted in a way that |
893 | // violates our invariants. |
894 | //===----------------------------------------------------------------------===// |
895 | |
896 | void *foo_rev95267(); |
897 | int bar_rev95267() { |
898 | char (*Callback_rev95267)(void) = (char (*)(void)) foo_rev95267; |
899 | if ((*Callback_rev95267)() == (char) 0) |
900 | return 1; |
901 | return 0; |
902 | } |
903 | |
904 | // Same as previous case, but handle casts to 'void'. |
905 | int bar_rev95274() { |
906 | void (*Callback_rev95274)(void) = (void (*)(void)) foo_rev95267; |
907 | (*Callback_rev95274)(); |
908 | return 0; |
909 | } |
910 | |
911 | void rdar7582031_test_static_init_zero() { |
912 | static unsigned x; |
913 | if (x == 0) |
914 | return; |
915 | int *p = 0; |
916 | *p = 0xDEADBEEF; |
917 | } |
918 | void rdar7582031_test_static_init_zero_b() { |
919 | static void* x; |
920 | if (x == 0) |
921 | return; |
922 | int *p = 0; |
923 | *p = 0xDEADBEEF; |
924 | } |
925 | |
926 | //===----------------------------------------------------------------------===// |
927 | // Test handling of parameters that are structs that contain floats and // |
928 | // nested fields. // |
929 | //===----------------------------------------------------------------------===// |
930 | |
931 | struct s_rev95547_nested { float x, y; }; |
932 | struct s_rev95547 { |
933 | struct s_rev95547_nested z1; |
934 | struct s_rev95547_nested z2; |
935 | }; |
936 | float foo_rev95547(struct s_rev95547 w) { |
937 | return w.z1.x + 20.0; // no-warning |
938 | } |
939 | void foo_rev95547_b(struct s_rev95547 w) { |
940 | struct s_rev95547 w2 = w; |
941 | w2.z1.x += 20.0; // no-warning |
942 | } |
943 | |
944 | //===----------------------------------------------------------------------===// |
945 | // Test handling statement expressions that don't populate a CFG block that |
946 | // is used to represent the computation of the RHS of a logical operator. |
947 | // This previously triggered a crash. |
948 | //===----------------------------------------------------------------------===// |
949 | |
950 | void pr6938() { |
951 | if (1 && ({ |
952 | while (0); |
953 | 0; |
954 | }) == 0) { |
955 | } |
956 | } |
957 | |
958 | void pr6938_b() { |
959 | if (1 && *({ // expected-warning{{Dereference of null pointer}} |
960 | while (0) {} |
961 | ({ |
962 | (int *) 0; |
963 | }); |
964 | }) == 0) { |
965 | } |
966 | } |
967 | |
968 | //===----------------------------------------------------------------------===// |
969 | // <rdar://problem/7979430> - The CFG for code containing an empty |
970 | // @synchronized block was previously broken (and would crash the analyzer). |
971 | //===----------------------------------------------------------------------===// |
972 | |
973 | void r7979430(id x) { |
974 | @synchronized(x) {} |
975 | } |
976 | |
977 | //===----------------------------------------------------------------------=== |
978 | // PR 7361 - Test that functions wrapped in macro instantiations are analyzed. |
979 | //===----------------------------------------------------------------------=== |
980 | #define MAKE_TEST_FN() \ |
981 | void test_pr7361 (char a) {\ |
982 | char* b = 0x0; *b = a;\ |
983 | } |
984 | |
985 | MAKE_TEST_FN() // expected-warning{{null pointer}} |
986 | |
987 | //===----------------------------------------------------------------------=== |
988 | // PR 7491 - Test that symbolic expressions can be used as conditions. |
989 | //===----------------------------------------------------------------------=== |
990 | |
991 | void pr7491 () { |
992 | extern int getint(); |
993 | int a = getint()-1; |
994 | if (a) { |
995 | return; |
996 | } |
997 | if (!a) { |
998 | return; |
999 | } else { |
1000 | // Should be unreachable |
1001 | (void)*(char*)0; // no-warning |
1002 | } |
1003 | } |
1004 | |
1005 | //===----------------------------------------------------------------------=== |
1006 | // PR 7475 - Test that assumptions about global variables are reset after |
1007 | // calling a global function. |
1008 | //===----------------------------------------------------------------------=== |
1009 | |
1010 | int *pr7475_someGlobal; |
1011 | void pr7475_setUpGlobal(); |
1012 | |
1013 | void pr7475() { |
1014 | if (pr7475_someGlobal == 0) |
1015 | pr7475_setUpGlobal(); |
1016 | *pr7475_someGlobal = 0; // no-warning |
1017 | } |
1018 | |
1019 | void pr7475_warn() { |
1020 | static int *someStatic = 0; |
1021 | if (someStatic == 0) |
1022 | pr7475_setUpGlobal(); |
1023 | *someStatic = 0; // expected-warning{{null pointer}} |
1024 | } |
1025 | |
1026 | // <rdar://problem/8202272> - __imag passed non-complex should not crash |
1027 | float f0(_Complex float x) { |
1028 | float l0 = __real x; |
1029 | return __real l0 + __imag l0; |
1030 | } |
1031 | |
1032 | |
1033 | //===----------------------------------------------------------------------=== |
1034 | // Test that we can reduce symbols to constants whether they are on the left |
1035 | // or right side of an expression. |
1036 | //===----------------------------------------------------------------------=== |
1037 | |
1038 | void reduce_to_constant(int x, int y) { |
1039 | if (x != 20) |
1040 | return; |
1041 | |
1042 | int a = x + y; |
1043 | int b = y + x; |
1044 | |
1045 | if (y == -20 && a != 0) |
1046 | (void)*(char*)0; // no-warning |
1047 | if (y == -20 && b != 0) |
1048 | (void)*(char*)0; // no-warning |
1049 | } |
1050 | |
1051 | // <rdar://problem/8360854> - Test that code after a switch statement with no |
1052 | // 'case:' labels is correctly evaluated. |
1053 | void r8360854(int n) { |
1054 | switch (n) { |
1055 | default: ; |
1056 | } |
1057 | int *p = 0; |
1058 | *p = 0xDEADBEEF; // expected-warning{{null pointer}} |
1059 | } |
1060 | |
1061 | // PR 8050 - crash in CastSizeChecker when pointee is an incomplete type |
1062 | typedef long unsigned int __darwin_size_t; |
1063 | typedef __darwin_size_t size_t; |
1064 | void *malloc(size_t); |
1065 | |
1066 | struct PR8050; |
1067 | |
1068 | void pr8050(struct PR8050 **arg) |
1069 | { |
1070 | *arg = malloc(1); |
1071 | } |
1072 | |
1073 | // <rdar://problem/5880430> Switch on enum should not consider default case live |
1074 | // if all enum values are covered |
1075 | enum Cases { C1, C2, C3, C4 }; |
1076 | void test_enum_cases(enum Cases C) { |
1077 | switch (C) { |
1078 | case C1: |
1079 | case C2: |
1080 | case C4: |
1081 | case C3: |
1082 | return; |
1083 | } |
1084 | int *p = 0; |
1085 | *p = 0xDEADBEEF; // no-warning |
1086 | } |
1087 | |
1088 | void test_enum_cases_positive(enum Cases C) { |
1089 | switch (C) { // expected-warning{{enumeration value 'C4' not handled in switch}} |
1090 | case C1: |
1091 | case C2: |
1092 | case C3: |
1093 | return; |
1094 | } |
1095 | int *p = 0; |
1096 | *p = 0xDEADBEEF; // expected-warning{{Dereference of null pointer}} |
1097 | } |
1098 | |
1099 | // <rdar://problem/6351970> rule request: warn if synchronization mutex can be nil |
1100 | void rdar6351970() { |
1101 | id x = 0; |
1102 | @synchronized(x) {} // expected-warning{{Nil value used as mutex for @synchronized() (no synchronization will occur)}} |
1103 | } |
1104 | |
1105 | void rdar6351970_b(id x) { |
1106 | if (!x) |
1107 | @synchronized(x) {} // expected-warning{{Nil value used as mutex for @synchronized() (no synchronization will occur)}} |
1108 | } |
1109 | |
1110 | void rdar6351970_c() { |
1111 | id x; |
1112 | @synchronized(x) {} // expected-warning{{Uninitialized value used as mutex for @synchronized}} |
1113 | } |
1114 | |
1115 | @interface Rdar8578650 |
1116 | - (id) foo8578650; |
1117 | @end |
1118 | |
1119 | void rdar8578650(id x) { |
1120 | @synchronized (x) { |
1121 | [x foo8578650]; |
1122 | } |
1123 | // At this point we should assume that 'x' is not nil, not |
1124 | // the inverse. |
1125 | @synchronized (x) { // no-warning |
1126 | } |
1127 | } |
1128 | |
1129 | // <rdar://problem/6352035> rule request: direct structure member access null pointer dereference |
1130 | @interface RDar6352035 { |
1131 | int c; |
1132 | } |
1133 | - (void)foo; |
1134 | - (void)bar; |
1135 | @end |
1136 | |
1137 | @implementation RDar6352035 |
1138 | - (void)foo { |
1139 | RDar6352035 *friend = 0; |
1140 | friend->c = 7; // expected-warning{{Access to instance variable 'c' results in a dereference of a null pointer (loaded from variable 'friend')}} |
1141 | } |
1142 | - (void)bar { |
1143 | self = 0; |
1144 | c = 7; // expected-warning{{Access to instance variable 'c' results in a dereference of a null pointer (loaded from variable 'self')}} |
1145 | } |
1146 | @end |
1147 | |
1148 | // PR 8149 - GNU statement expression in condition of ForStmt. |
1149 | // This previously triggered an assertion failure in CFGBuilder. |
1150 | void pr8149(void) { |
1151 | for (; ({ do { } while (0); 0; });) { } |
1152 | } |
1153 | |
1154 | // PR 8458 - Make sure @synchronized doesn't crash with properties. |
1155 | @interface PR8458 {} |
1156 | @property(readonly) id lock; |
1157 | @end |
1158 | |
1159 | static |
1160 | void __PR8458(PR8458 *x) { |
1161 | @synchronized(x.lock) {} // no-warning |
1162 | } |
1163 | |
1164 | // PR 8440 - False null dereference during store to array-in-field-in-global. |
1165 | // This test case previously resulted in a bogus null deref warning from |
1166 | // incorrect lazy symbolication logic in RegionStore. |
1167 | static struct { |
1168 | int num; |
1169 | char **data; |
1170 | } saved_pr8440; |
1171 | |
1172 | char *foo_pr8440(); |
1173 | char **bar_pr8440(); |
1174 | void baz_pr8440(int n) |
1175 | { |
1176 | saved_pr8440.num = n; |
1177 | if (saved_pr8440.data) |
1178 | return; |
1179 | saved_pr8440.data = bar_pr8440(); |
1180 | for (int i = 0 ; i < n ; i ++) |
1181 | saved_pr8440.data[i] = foo_pr8440(); // no-warning |
1182 | } |
1183 | |
1184 | // Support direct accesses to non-null memory. Reported in: |
1185 | // PR 5272 |
1186 | // <rdar://problem/6839683> |
1187 | int test_direct_address_load() { |
1188 | int *p = (int*) 0x4000; |
1189 | return *p; // no-warning |
1190 | } |
1191 | |
1192 | void pr5272_test() { |
1193 | struct pr5272 { int var2; }; |
1194 | (*(struct pr5272*)0xBC000000).var2 = 0; // no-warning |
1195 | (*(struct pr5272*)0xBC000000).var2 += 2; // no-warning |
1196 | } |
1197 | |
1198 | // Support casting the return value of function to another different type |
1199 | // This previously caused a crash, although we likely need more precise |
1200 | // reasoning here. <rdar://problem/8663544> |
1201 | void* rdar8663544(); |
1202 | typedef struct {} Val8663544; |
1203 | Val8663544 bazR8663544() { |
1204 | Val8663544(*func) () = (Val8663544(*) ()) rdar8663544; |
1205 | return func(); |
1206 | } |
1207 | |
1208 | // PR 8619 - Handle ternary expressions with a call to a noreturn function. |
1209 | // This previously resulted in a crash. |
1210 | void pr8619_noreturn(int x) __attribute__((noreturn)); |
1211 | |
1212 | void pr8619(int a, int b, int c) { |
1213 | a ?: pr8619_noreturn(b || c); |
1214 | } |
1215 | |
1216 | |
1217 | // PR 8646 - crash in the analyzer when handling unions. |
1218 | union pr8648_union { |
1219 | signed long long pr8648_union_field; |
1220 | }; |
1221 | void pr8648() { |
1222 | long long y; |
1223 | union pr8648_union x = { .pr8648_union_field = 0LL }; |
1224 | y = x.pr8648_union_field; |
1225 | |
1226 | union pr8648_union z; |
1227 | z = (union pr8648_union) { .pr8648_union_field = 0LL }; |
1228 | |
1229 | union pr8648_union w; |
1230 | w = ({ (union pr8648_union) { .pr8648_union_field = 0LL }; }); |
1231 | |
1232 | // crash, no assignment |
1233 | (void) ({ (union pr8648_union) { .pr8648_union_field = 0LL }; }).pr8648_union_field; |
1234 | |
1235 | // crash with assignment |
1236 | y = ({ (union pr8648_union) { .pr8648_union_field = 0LL }; }).pr8648_union_field; |
1237 | } |
1238 | |
1239 | // PR 9269 - don't assert when building the following CFG. The for statement |
1240 | // contains a condition with multiple basic blocks, and the value of the |
1241 | // statement expression is then indexed as part of a bigger condition expression. |
1242 | // This example exposed a bug in child traversal in the CFGBuilder. |
1243 | void pr9269() { |
1244 | struct s { char *bar[10]; } baz[2] = { 0 }; |
1245 | unsigned i = 0; |
1246 | for (i = 0; |
1247 | (* ({ while(0); ({ &baz[0]; }); })).bar[0] != 0; // expected-warning {{while loop has empty body}} expected-note {{put the semicolon on a separate line to silence this warning}} |
1248 | ++i) {} |
1249 | } |
1250 | |
1251 | // Test evaluation of GNU-style ?:. |
1252 | int pr9287(int type) { return type ? : 0; } // no-warning |
1253 | |
1254 | void pr9287_b(int type, int *p) { |
1255 | int x = type ? : 0; |
1256 | if (x) { |
1257 | p = 0; |
1258 | } |
1259 | if (type) { |
1260 | *p = 0xDEADBEEF; // expected-warning {{null pointer}} |
1261 | } |
1262 | } |
1263 | |
1264 | void pr9287_c(int type, int *p) { |
1265 | int x = type ? : 0; |
1266 | if (x) { |
1267 | p = 0; |
1268 | } |
1269 | if (!type) { |
1270 | *p = 0xDEADBEEF; // no-warning |
1271 | } |
1272 | } |
1273 | |
1274 | void test_switch() { |
1275 | switch (4) { |
1276 | case 1: { |
1277 | int *p = 0; |
1278 | *p = 0xDEADBEEF; // no-warning |
1279 | break; |
1280 | } |
1281 | case 4: { |
1282 | int *p = 0; |
1283 | *p = 0xDEADBEEF; // expected-warning {{null}} |
1284 | break; |
1285 | } |
1286 | default: { |
1287 | int *p = 0; |
1288 | *p = 0xDEADBEEF; // no-warning |
1289 | break; |
1290 | } |
1291 | } |
1292 | } |
1293 | |
1294 | // PR 9467. Tests various CFG optimizations. This previously crashed. |
1295 | static void test(unsigned int bit_mask) |
1296 | { |
1297 | unsigned int bit_index; |
1298 | for (bit_index = 0; |
1299 | bit_index < 24; |
1300 | bit_index++) { |
1301 | switch ((0x01 << bit_index) & bit_mask) { |
1302 | case 0x100000: ; |
1303 | } |
1304 | } |
1305 | } |
1306 | |
1307 | // Don't crash on code containing __label__. |
1308 | int radar9414427_aux(); |
1309 | void radar9414427() { |
1310 | __label__ mylabel; |
1311 | if (radar9414427_aux()) { |
1312 | mylabel: do {} |
1313 | while (0); |
1314 | } |
1315 | } |
1316 | |
1317 | // Analyze methods in @implementation (category) |
1318 | @interface RDar9465344 |
1319 | @end |
1320 | |
1321 | @implementation RDar9465344 (MyCategory) |
1322 | - (void) testcategoryImpl { |
1323 | int *p = 0x0; |
1324 | *p = 0xDEADBEEF; // expected-warning {{null}} |
1325 | } |
1326 | @end |
1327 | |
1328 | @implementation RDar9465344 |
1329 | @end |
1330 | |
1331 | // Don't crash when analyzing access to 'self' within a block. |
1332 | @interface Rdar10380300Base |
1333 | - (void) foo; |
1334 | @end |
1335 | @interface Rdar10380300 : Rdar10380300Base @end |
1336 | @implementation Rdar10380300 |
1337 | - (void)foo { |
1338 | ^{ |
1339 | [super foo]; |
1340 | }(); |
1341 | } |
1342 | @end |
1343 | |
1344 | // Don't crash when a ?: is only preceded by a statement (not an expression) |
1345 | // in the CFG. |
1346 | void __assert_fail(); |
1347 | |
1348 | enum rdar1196620_e { E_A, E_B, E_C, E_D }; |
1349 | struct rdar1196620_s { int ints[E_D+1]; }; |
1350 | |
1351 | static void rdar1196620_call_assert(struct rdar1196620_s* s) { |
1352 | int i = 0; |
1353 | s?(void)0:__assert_fail(); |
1354 | } |
1355 | |
1356 | static void rdar1196620(struct rdar1196620_s* s) { |
1357 | rdar1196620_call_assert(s); |
1358 | } |
1359 | |
1360 | |
1361 | |