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 -
3
4//===----------------------------------------------------------------------===//
5// Forward declarations (from headers).
6//===----------------------------------------------------------------------===//
7
8typedef const struct __CFNumber * CFNumberRef;
9typedef const struct __CFAllocator * CFAllocatorRef;
10extern const CFAllocatorRef kCFAllocatorDefault;
11typedef signed long CFIndex;
12enum {
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
30};
31typedef CFIndex CFNumberType;
32CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr);
33
34#define nil ((id)0)
35
36__attribute__((objc_root_class))
37@interface NSObject
38+ (instancetype) alloc;
39- (instancetype) init;
40- (instancetype)retain;
41- (void)release;
42@end
43
44@interface NSArray : NSObject
45@end
46
47//===----------------------------------------------------------------------===//
48// Basic tracking of null and tests for null.
49//===----------------------------------------------------------------------===//
50
51void test_null_init(void) {
52  int *p = 0;
53  *p = 0xDEADBEEF;
54}
55
56void test_null_assign(void) {
57  int *p;
58  p = 0;
59  *p = 0xDEADBEEF;
60}
61
62void test_null_assign_transitive(void) {
63  int *p;
64  p = 0;
65  int *q = p;
66  *q = 0xDEADBEEF;
67}
68
69void test_null_cond(int *p) {
70  if (!p) {
71    *p = 0xDEADBEEF;
72  }
73}
74
75void test_null_cond_transitive(int *q) {
76  if (!q) {
77    int *p = q;
78    *p = 0xDEADBEEF;
79  }
80}
81
82void test_null_field(void) {
83  struct s { int *p; } x;
84  x.p = 0;
85  *(x.p) = 0xDEADBEEF;
86}
87
88void test_assumptions(int a, int b)
89{
90  if (a == 0) {
91    return;
92  }
93  if (b != 0) {
94    return;
95  }
96  int *p = 0;
97  *p = 0xDEADBEEF;
98}
99
100int *bar_cond_assign();
101int test_cond_assign() {
102  int *p;
103  if ((p = bar_cond_assign()))
104    return 1;
105  return *p;
106}
107
108//===----------------------------------------------------------------------===//
109// Diagnostics for leaks and "noreturn" paths.
110//===----------------------------------------------------------------------===//
111
112
113// <rdar://problem/8331641> leak reports should not show paths that end with exit() (but ones that don't end with exit())
114
115void stop() __attribute__((noreturn));
116
117void 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;
123}
124
125//===----------------------------------------------------------------------===//
126// Test loops and control-flow.
127//===----------------------------------------------------------------------===//
128
129void test_objc_fast_enumeration(NSArray *x) {
130  id obj;
131  for (obj in x)
132    *(volatile int *)0 = 0;
133}
134
135void test_objc_fast_enumeration_2(id arr) {
136  int x;
137  for (id obj in arr) {
138    x = 1;
139  }
140  x += 1;
141}
142
143// Test that loops are documented in the path.
144void 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  }
151}
152
153// Test for a "loop executed 0 times" diagnostic.
154int *radar12322528_bar();
155
156void 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;
163}
164
165void 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;
173}
174
175void radar12322528_foo_2() {
176  int *p = 0;
177  for (unsigned i = 0; i < 2; ++i) {
178    if (i == 0)
179      continue;
180
181    if (i == 1) {
182
183      break;
184    }
185  }
186  *p = 0xDEADBEEF;
187}
188
189void test_loop_diagnostics() {
190  int *p = 0;
191  for (int i = 0; i < 2; ++i) { p = 0; }
192  *p = 1;
193}
194
195void test_loop_diagnostics_2() {
196  int *p = 0;
197
198  for (int i = 0; i < 2; ) {
199
200    ++i;
201
202    p = 0;
203
204  }
205
206  *p = 1;
207}
208
209void 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;
220}
221
222void test_do_while() {
223  unsigned i = 0;
224
225  int *p;
226
227  do {
228
229    ++i;
230    p = 0;
231
232  } while (i< 2);
233
234  *p = 0xDEADBEEF;
235}
236
237
238void test_logical_and() {
239  int *p = 0;
240  if (1 && 2) {
241    *p = 0xDEADBEEF;
242  }
243}
244
245void test_logical_or() {
246  int *p = 0;
247  if (0 || 2) {
248    *p = 0xDEADBEEF;
249  }
250}
251
252void test_logical_or_call() {
253  extern int call(int);
254  int *p = 0;
255  if (call(0 || 2)) {
256    *p = 0xDEADBEEF;
257  }
258}
259
260void test_nested_logicals(int coin) {
261  int *p = 0;
262
263  if ((0 || 0) || coin) {
264    *p = 0xDEADBEEF;
265  }
266
267  if (0 || (0 || !coin)) {
268    *p = 0xDEADBEEF;
269  }
270}
271
272void test_deeply_nested_logicals() {
273  extern int call(int);
274  int *p = 0;
275
276  if ((0 || (5 && 0)) ? 0 : ((0 || 4) ? call(1 && 5) : 0)) {
277
278    *p = 0xDEADBEEF;
279  }
280}
281
282void test_ternary(int x, int *y) {
283  int z = x ? 0 : 1;
284
285  int *p = z ? y : 0;
286
287  *p = 0xDEADBEEF;
288}
289
290void testUseless(int *y) {
291  if (y) {
292
293  }
294  if (y) {
295
296  }
297  int *p = 0;
298  *p = 0xDEADBEEF;
299}
300
301//===----------------------------------------------------------------------===//
302// Interprocedural tests.
303//===----------------------------------------------------------------------===//
304
305@interface IPA_Foo
306- (int *) returnsPointer;
307@end
308
309int testFoo(IPA_Foo *x) {
310  if (x)
311    return 1;
312  return *[x returnsPointer];
313}
314
315@interface IPA_X : NSObject
316- (int *)getPointer;
317@end
318
319void test1_IPA_X() {
320  IPA_X *x = nil;
321  *[x getPointer] = 1; // here
322}
323
324
325@interface IPA_Y : NSObject
326- (IPA_Y *)opaque;
327- (IPA_X *)getX;
328@end
329
330@implementation IPA_Y
331- (IPA_X *)getX {
332  return nil;
333}
334@end
335
336void test_IPA_Y(IPA_Y *y) {
337  if (y)
338    return;
339
340  IPA_X *x = [[y opaque] getX]; // here
341  *[x getPointer] = 1;
342}
343
344// From diagnostics/report-issues-within-main-file.cpp:
345void causeDivByZeroInMain(int in) {
346  int m = 0;
347  m = in/m;
348  m++;
349}
350
351void mainPlusMain() {
352  int i = 0;
353  i++;
354  causeDivByZeroInMain(i);
355  i++;
356}
357
358// From inlining/path-notes.c:
359int *getZero() {
360  int *p = 0;
361  return p;
362}
363
364void usePointer(int *p) {
365  *p = 1;
366}
367
368void testUseOfNullPointer() {
369  // Test the case where an argument expression is itself a call.
370  usePointer(getZero());
371}
372
373
374//===----------------------------------------------------------------------===//
375// Misc. tests.
376//===----------------------------------------------------------------------===//
377
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;
385}
386@end
387
388// Test diagnostics for initialization of structs.
389void RDar13295437_f(void *i) __attribute__((__nonnull__));
390struct RDar13295437_S { int *i; };
391int  RDar13295437() {
392  struct RDar13295437_S s = {0};
393  struct RDar13295437_S *sp = &s;
394  RDar13295437_f(sp->i);
395  return 0;
396}
397
398
399void testCast(int coin) {
400  if (coin) {
401    (void)(1+2);
402    (void)(2+3);
403    (void)(3+4);
404    *(volatile int *)0 = 1;
405  }
406}
407
408// The following previously crashed when generating extensive diagnostics.
409// <rdar://problem/10797980>
410@interface RDar10797980_help
411@property (readonly) int x;
412@end
413@interface RDar10797980 : NSObject {
414  RDar10797980_help *y;
415}
416- (void) test;
417@end
418@implementation RDar10797980
419- (void) test {
420  if (y.x == 1) {
421    int *p = 0;
422    *p = 0xDEADBEEF; // expected-warning {{deference}}
423  }
424}
425
426// The original source for the above Radar contains another problem:
427// if the end-of-path node is an implicit statement, it may not have a valid
428// source location. <rdar://problem/12446776>
429- (void)test2 {
430  if (bar_cond_assign()) {
431    id foo = [[RDar10797980 alloc] init]; // leak
432  }
433  (void)y; // first statement after the 'if' is an implicit 'self' DeclRefExpr
434}
435
436@end
437
438void variousLoops(id input) {
439  extern int a();
440  extern int b();
441  extern int c();
442
443  extern int work();
444
445  while (a()) {
446    work();
447    work();
448    work();
449    *(volatile int *)0 = 1;
450  }
451
452  int first = 1;
453  do {
454    work();
455    work();
456    work();
457    if (!first)
458      *(volatile int *)0 = 1;
459    first = 0;
460  } while (a());
461
462  for (int i = 0; i != b(); ++i) {
463    work();
464    *(volatile int *)0 = 1;
465  }
466
467  for (id x in input) {
468    work();
469    work();
470    work();
471    (void)x;
472    *(volatile int *)0 = 1;
473  }
474
475  int z[] = {1,2};
476  for (int y : z) {
477    work();
478    work();
479    work();
480    (void)y;
481  }
482
483  int empty[] = {};
484  for (int y : empty) {
485    work();
486    work();
487    work();
488    (void)y;
489  }
490
491  for (int i = 0; ; ++i) {
492    work();
493    if (i == b())
494      break;
495  }
496
497  int i;
498  for (i = 0; i != b(); ++i) {
499    work();
500    *(volatile int *)0 = 1;
501  }
502
503  for (; i != b(); ++i) {
504    work();
505    *(volatile int *)0 = 1;
506  }
507
508  for (; i != b(); ) {
509    work();
510    if (i == b())
511      break;
512    *(volatile int *)0 = 1;
513  }
514
515  for (;;) {
516    work();
517    if (i == b())
518      break;
519  }
520
521  *(volatile int *)0 = 1;
522}
523
524void *malloc(unsigned long);
525void *realloc(void *, unsigned long);
526void free(void *);
527
528void reallocDiagnostics() {
529  char * buf = (char*)malloc(100);
530  char * tmp;
531  tmp = (char*)realloc(buf, 0x1000000);
532  if (!tmp) {
533    return;// expected-warning {{leak}}
534  }
535  buf = tmp;
536  free(buf);
537}
538
539template <typename T>
540class unique_ptr {
541  T *ptr;
542public:
543  explicit unique_ptr(T *p) : ptr(p) {}
544  ~unique_ptr() { delete ptr; }
545};
546
547void test() {
548  int i = 0;
549  ++i;
550
551  unique_ptr<int> p(new int[4]);
552  {
553    ++i;
554  }
555}
556
557void longLines() {
558  id foo = [[NSObject alloc] init]; // leak
559  id bar =
560           [foo retain];
561  [bar release];
562  id baz = [foo
563              retain];
564  [baz release];
565  // This next line is intentionally longer than 80 characters.
566  id garply = [foo                                                              retain];
567  [garply release];
568}
569
570#define POINTER(T) T*
571POINTER(void) testMacroInFunctionDecl(void *q) {
572  int *p = 0;
573  *p = 1;
574  return q;
575}
576
577namespace rdar14960554 {
578  class Foo {
579    int a = 1;
580    int b = 2;
581    int c = 3;
582
583    Foo() :
584      a(0),
585      c(3) {
586      // Check that we don't have an edge to the in-class initializer for 'b'.
587      if (b == 2)
588        *(volatile int *)0 = 1;
589    }
590  };
591}
592
593