Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / Analysis / edges-new.mm
blobe87e6010a04415cf49911bf8c8287019df9e2cd4
1 // RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,deadcode.DeadStores,osx.cocoa.RetainCount,unix.Malloc,unix.MismatchedDeallocator -analyzer-output=plist -analyzer-config deadcode.DeadStores:ShowFixIts=true -o %t -w %s
2 // RUN: %normalize_plist <%t | diff -ub %S/Inputs/expected-plists/edges-new.mm.plist -
4 //===----------------------------------------------------------------------===//
5 // Forward declarations (from headers).
6 //===----------------------------------------------------------------------===//
8 typedef const struct __CFNumber * CFNumberRef;
9 typedef const struct __CFAllocator * CFAllocatorRef;
10 extern const CFAllocatorRef kCFAllocatorDefault;
11 typedef signed long CFIndex;
12 enum {
13   kCFNumberSInt8Type = 1,
14   kCFNumberSInt16Type = 2,
15   kCFNumberSInt32Type = 3,
16   kCFNumberSInt64Type = 4,
17   kCFNumberFloat32Type = 5,
18   kCFNumberFloat64Type = 6,
19   kCFNumberCharType = 7,
20   kCFNumberShortType = 8,
21   kCFNumberIntType = 9,
22   kCFNumberLongType = 10,
23   kCFNumberLongLongType = 11,
24   kCFNumberFloatType = 12,
25   kCFNumberDoubleType = 13,
26   kCFNumberCFIndexType = 14,
27   kCFNumberNSIntegerType = 15,
28   kCFNumberCGFloatType = 16,
29   kCFNumberMaxType = 16
31 typedef CFIndex CFNumberType;
32 CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr);
34 #define nil ((id)0)
36 __attribute__((objc_root_class))
37 @interface NSObject
38 + (instancetype) alloc;
39 - (instancetype) init;
40 - (instancetype)retain;
41 - (void)release;
42 @end
44 @interface NSArray : NSObject
45 @end
47 //===----------------------------------------------------------------------===//
48 // Basic tracking of null and tests for null.
49 //===----------------------------------------------------------------------===//
51 void test_null_init(void) {
52   int *p = 0;
53   *p = 0xDEADBEEF;
56 void test_null_assign(void) {
57   int *p;
58   p = 0;
59   *p = 0xDEADBEEF;
62 void test_null_assign_transitive(void) {
63   int *p;
64   p = 0;
65   int *q = p;
66   *q = 0xDEADBEEF;
69 void test_null_cond(int *p) {
70   if (!p) {
71     *p = 0xDEADBEEF;
72   }
75 void test_null_cond_transitive(int *q) {
76   if (!q) {
77     int *p = q;
78     *p = 0xDEADBEEF;
79   }
82 void test_null_field(void) {
83   struct s { int *p; } x;
84   x.p = 0;
85   *(x.p) = 0xDEADBEEF;
88 void test_assumptions(int a, int b)
90   if (a == 0) {
91     return;
92   }
93   if (b != 0) {
94     return;
95   }
96   int *p = 0;
97   *p = 0xDEADBEEF;
100 int *bar_cond_assign();
101 int test_cond_assign() {
102   int *p;
103   if ((p = bar_cond_assign()))
104     return 1;
105   return *p;
108 //===----------------------------------------------------------------------===//
109 // Diagnostics for leaks and "noreturn" paths.
110 //===----------------------------------------------------------------------===//
113 // leak reports should not show paths that end with exit() (but ones that don't end with exit())
115 void stop() __attribute__((noreturn));
117 void rdar8331641(int x) {
118   signed z = 1;
119   CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // expected-warning{{leak}}
120   if (x)
121     stop();
122   (void) value;
125 //===----------------------------------------------------------------------===//
126 // Test loops and control-flow.
127 //===----------------------------------------------------------------------===//
129 void test_objc_fast_enumeration(NSArray *x) {
130   id obj;
131   for (obj in x)
132     *(volatile int *)0 = 0;
135 void test_objc_fast_enumeration_2(id arr) {
136   int x;
137   for (id obj in arr) {
138     x = 1;
139   }
140   x += 1;
143 // Test that loops are documented in the path.
144 void rdar12280665() {
145   for (unsigned i = 0; i < 2; ++i) {
146           if (i == 1) {
147                   int *p = 0;
148                   *p = 0xDEADBEEF; // expected-warning {{dereference}}
149           }
150   }
153 // Test for a "loop executed 0 times" diagnostic.
154 int *radar12322528_bar();
156 void radar12322528_for(int x) {
157   int z;
158   int *p = 0;
159   for (unsigned i = 0; i < x; ++i) {
160     p = radar12322528_bar();
161   }
162   *p = 0xDEADBEEF;
165 void radar12322528_while(int x) {
166   int *p = 0;
167   unsigned i = 0;
168   for ( ; i < x ; ) {
169     ++i;
170     p = radar12322528_bar();
171   }
172   *p = 0xDEADBEEF;
175 void radar12322528_foo_2() {
176   int *p = 0;
177   for (unsigned i = 0; i < 2; ++i) {
178     if (i == 0)
179       continue;
181     if (i == 1) {
183       break;
184     }
185   }
186   *p = 0xDEADBEEF;
189 void test_loop_diagnostics() {
190   int *p = 0;
191   for (int i = 0; i < 2; ++i) { p = 0; }
192   *p = 1;
195 void test_loop_diagnostics_2() {
196   int *p = 0;
198   for (int i = 0; i < 2; ) {
200     ++i;
202     p = 0;
204   }
206   *p = 1;
209 void test_loop_diagnostics_3() {
210   int z;
211   int y;
212   int k;
213   int *p = 0;
214   int i = 0;
215   while (i < 2) {
216     ++i;
217     p = 0;
218   }
219   * p = 1;
222 void test_do_while() {
223   unsigned i = 0;
225   int *p;
227   do {
229     ++i;
230     p = 0;
232   } while (i< 2);
234   *p = 0xDEADBEEF;
238 void test_logical_and() {
239   int *p = 0;
240   if (1 && 2) {
241     *p = 0xDEADBEEF;
242   }
245 void test_logical_or() {
246   int *p = 0;
247   if (0 || 2) {
248     *p = 0xDEADBEEF;
249   }
252 void test_logical_or_call() {
253   extern int call(int);
254   int *p = 0;
255   if (call(0 || 2)) {
256     *p = 0xDEADBEEF;
257   }
260 void test_nested_logicals(int coin) {
261   int *p = 0;
263   if ((0 || 0) || coin) {
264     *p = 0xDEADBEEF;
265   }
267   if (0 || (0 || !coin)) {
268     *p = 0xDEADBEEF;
269   }
272 void test_deeply_nested_logicals() {
273   extern int call(int);
274   int *p = 0;
276   if ((0 || (5 && 0)) ? 0 : ((0 || 4) ? call(1 && 5) : 0)) {
278     *p = 0xDEADBEEF;
279   }
282 void test_ternary(int x, int *y) {
283   int z = x ? 0 : 1;
285   int *p = z ? y : 0;
287   *p = 0xDEADBEEF;
290 void testUseless(int *y) {
291   if (y) {
293   }
294   if (y) {
296   }
297   int *p = 0;
298   *p = 0xDEADBEEF;
301 //===----------------------------------------------------------------------===//
302 // Interprocedural tests.
303 //===----------------------------------------------------------------------===//
305 @interface IPA_Foo
306 - (int *) returnsPointer;
307 @end
309 int testFoo(IPA_Foo *x) {
310   if (x)
311     return 1;
312   return *[x returnsPointer];
315 @interface IPA_X : NSObject
316 - (int *)getPointer;
317 @end
319 void test1_IPA_X() {
320   IPA_X *x = nil;
321   *[x getPointer] = 1; // here
325 @interface IPA_Y : NSObject
326 - (IPA_Y *)opaque;
327 - (IPA_X *)getX;
328 @end
330 @implementation IPA_Y
331 - (IPA_X *)getX {
332   return nil;
334 @end
336 void test_IPA_Y(IPA_Y *y) {
337   if (y)
338     return;
340   IPA_X *x = [[y opaque] getX]; // here
341   *[x getPointer] = 1;
344 // From diagnostics/report-issues-within-main-file.cpp:
345 void causeDivByZeroInMain(int in) {
346   int m = 0;
347   m = in/m;
348   m++;
351 void mainPlusMain() {
352   int i = 0;
353   i++;
354   causeDivByZeroInMain(i);
355   i++;
358 // From inlining/path-notes.c:
359 int *getZero() {
360   int *p = 0;
361   return p;
364 void usePointer(int *p) {
365   *p = 1;
368 void testUseOfNullPointer() {
369   // Test the case where an argument expression is itself a call.
370   usePointer(getZero());
374 //===----------------------------------------------------------------------===//
375 // Misc. tests.
376 //===----------------------------------------------------------------------===//
378 // Test for tracking null state of ivars.
379 @interface RDar12114812 : NSObject  { char *p; }
380 @end
381 @implementation RDar12114812
382 - (void)test {
383   p = 0;
384   *p = 1;
386 @end
388 // Test diagnostics for initialization of structs.
389 void RDar13295437_f(void *i) __attribute__((__nonnull__));
390 struct RDar13295437_S { int *i; };
391 int  RDar13295437() {
392   struct RDar13295437_S s = {0};
393   struct RDar13295437_S *sp = &s;
394   RDar13295437_f(sp->i);
395   return 0;
399 void testCast(int coin) {
400   if (coin) {
401     (void)(1+2);
402     (void)(2+3);
403     (void)(3+4);
404     *(volatile int *)0 = 1;
405   }
408 // The following previously crashed when generating extensive diagnostics.
409 @interface RDar10797980_help
410 @property (readonly) int x;
411 @end
412 @interface RDar10797980 : NSObject {
413   RDar10797980_help *y;
415 - (void) test;
416 @end
417 @implementation RDar10797980
418 - (void) test {
419   if (y.x == 1) {
420     int *p = 0;
421     *p = 0xDEADBEEF; // expected-warning {{deference}}
422   }
425 // The original source for the above Radar contains another problem:
426 // if the end-of-path node is an implicit statement, it may not have a valid
427 // source location.
428 - (void)test2 {
429   if (bar_cond_assign()) {
430     id foo = [[RDar10797980 alloc] init]; // leak
431   }
432   (void)y; // first statement after the 'if' is an implicit 'self' DeclRefExpr
435 @end
437 void variousLoops(id input) {
438   extern int a();
439   extern int b();
440   extern int c();
442   extern int work();
444   while (a()) {
445     work();
446     work();
447     work();
448     *(volatile int *)0 = 1;
449   }
451   int first = 1;
452   do {
453     work();
454     work();
455     work();
456     if (!first)
457       *(volatile int *)0 = 1;
458     first = 0;
459   } while (a());
461   for (int i = 0; i != b(); ++i) {
462     work();
463     *(volatile int *)0 = 1;
464   }
466   for (id x in input) {
467     work();
468     work();
469     work();
470     (void)x;
471     *(volatile int *)0 = 1;
472   }
474   int z[] = {1,2};
475   for (int y : z) {
476     work();
477     work();
478     work();
479     (void)y;
480   }
482   int empty[] = {};
483   for (int y : empty) {
484     work();
485     work();
486     work();
487     (void)y;
488   }
490   for (int i = 0; ; ++i) {
491     work();
492     if (i == b())
493       break;
494   }
496   int i;
497   for (i = 0; i != b(); ++i) {
498     work();
499     *(volatile int *)0 = 1;
500   }
502   for (; i != b(); ++i) {
503     work();
504     *(volatile int *)0 = 1;
505   }
507   for (; i != b(); ) {
508     work();
509     if (i == b())
510       break;
511     *(volatile int *)0 = 1;
512   }
514   for (;;) {
515     work();
516     if (i == b())
517       break;
518   }
520   *(volatile int *)0 = 1;
523 void *malloc(unsigned long);
524 void *realloc(void *, unsigned long);
525 void free(void *);
527 void reallocDiagnostics() {
528   char * buf = (char*)malloc(100);
529   char * tmp;
530   tmp = (char*)realloc(buf, 0x1000000);
531   if (!tmp) {
532     return;// expected-warning {{leak}}
533   }
534   buf = tmp;
535   free(buf);
538 template <typename T>
539 class unique_ptr {
540   T *ptr;
541 public:
542   explicit unique_ptr(T *p) : ptr(p) {}
543   ~unique_ptr() { delete ptr; }
546 void test() {
547   int i = 0;
548   ++i;
550   unique_ptr<int> p(new int[4]);
551   {
552     ++i;
553   }
556 void longLines() {
557   id foo = [[NSObject alloc] init]; // leak
558   id bar =
559            [foo retain];
560   [bar release];
561   id baz = [foo
562               retain];
563   [baz release];
564   // This next line is intentionally longer than 80 characters.
565   id garply = [foo                                                              retain];
566   [garply release];
569 #define POINTER(T) T*
570 POINTER(void) testMacroInFunctionDecl(void *q) {
571   int *p = 0;
572   *p = 1;
573   return q;
576 namespace rdar14960554 {
577   class Foo {
578     int a = 1;
579     int b = 2;
580     int c = 3;
582     Foo() :
583       a(0),
584       c(3) {
585       // Check that we don't have an edge to the in-class initializer for 'b'.
586       if (b == 2)
587         *(volatile int *)0 = 1;
588     }
589   };