| // 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 | 
 | // RUN: %normalize_plist <%t | diff -ub %S/Inputs/expected-plists/edges-new.mm.plist - | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | // Forward declarations (from headers). | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | typedef const struct __CFNumber * CFNumberRef; | 
 | typedef const struct __CFAllocator * CFAllocatorRef; | 
 | extern const CFAllocatorRef kCFAllocatorDefault; | 
 | typedef signed long CFIndex; | 
 | enum { | 
 |   kCFNumberSInt8Type = 1, | 
 |   kCFNumberSInt16Type = 2, | 
 |   kCFNumberSInt32Type = 3, | 
 |   kCFNumberSInt64Type = 4, | 
 |   kCFNumberFloat32Type = 5, | 
 |   kCFNumberFloat64Type = 6, | 
 |   kCFNumberCharType = 7, | 
 |   kCFNumberShortType = 8, | 
 |   kCFNumberIntType = 9, | 
 |   kCFNumberLongType = 10, | 
 |   kCFNumberLongLongType = 11, | 
 |   kCFNumberFloatType = 12, | 
 |   kCFNumberDoubleType = 13, | 
 |   kCFNumberCFIndexType = 14, | 
 |   kCFNumberNSIntegerType = 15, | 
 |   kCFNumberCGFloatType = 16, | 
 |   kCFNumberMaxType = 16 | 
 | }; | 
 | typedef CFIndex CFNumberType; | 
 | CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr); | 
 |  | 
 | #define nil ((id)0) | 
 |  | 
 | __attribute__((objc_root_class)) | 
 | @interface NSObject | 
 | + (instancetype) alloc; | 
 | - (instancetype) init; | 
 | - (instancetype)retain; | 
 | - (void)release; | 
 | @end | 
 |  | 
 | @interface NSArray : NSObject | 
 | @end | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | // Basic tracking of null and tests for null. | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | void test_null_init(void) { | 
 |   int *p = 0; | 
 |   *p = 0xDEADBEEF; | 
 | } | 
 |  | 
 | void test_null_assign(void) { | 
 |   int *p; | 
 |   p = 0; | 
 |   *p = 0xDEADBEEF; | 
 | } | 
 |  | 
 | void test_null_assign_transitive(void) { | 
 |   int *p; | 
 |   p = 0; | 
 |   int *q = p; | 
 |   *q = 0xDEADBEEF; | 
 | } | 
 |  | 
 | void test_null_cond(int *p) { | 
 |   if (!p) { | 
 |     *p = 0xDEADBEEF; | 
 |   } | 
 | } | 
 |  | 
 | void test_null_cond_transitive(int *q) { | 
 |   if (!q) { | 
 |     int *p = q; | 
 |     *p = 0xDEADBEEF; | 
 |   } | 
 | } | 
 |  | 
 | void test_null_field(void) { | 
 |   struct s { int *p; } x; | 
 |   x.p = 0; | 
 |   *(x.p) = 0xDEADBEEF; | 
 | } | 
 |  | 
 | void test_assumptions(int a, int b) | 
 | { | 
 |   if (a == 0) { | 
 |     return; | 
 |   } | 
 |   if (b != 0) { | 
 |     return; | 
 |   } | 
 |   int *p = 0; | 
 |   *p = 0xDEADBEEF; | 
 | } | 
 |  | 
 | int *bar_cond_assign(); | 
 | int test_cond_assign() { | 
 |   int *p; | 
 |   if ((p = bar_cond_assign())) | 
 |     return 1; | 
 |   return *p; | 
 | } | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | // Diagnostics for leaks and "noreturn" paths. | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 |  | 
 | // leak reports should not show paths that end with exit() (but ones that don't end with exit()) | 
 |  | 
 | void stop() __attribute__((noreturn)); | 
 |  | 
 | void rdar8331641(int x) { | 
 |   signed z = 1; | 
 |   CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // expected-warning{{leak}} | 
 |   if (x) | 
 |     stop(); | 
 |   (void) value; | 
 | } | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | // Test loops and control-flow. | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | void test_objc_fast_enumeration(NSArray *x) { | 
 |   id obj; | 
 |   for (obj in x) | 
 |     *(volatile int *)0 = 0; | 
 | } | 
 |  | 
 | void test_objc_fast_enumeration_2(id arr) { | 
 |   int x; | 
 |   for (id obj in arr) { | 
 |     x = 1; | 
 |   } | 
 |   x += 1; | 
 | } | 
 |  | 
 | // Test that loops are documented in the path. | 
 | void rdar12280665() { | 
 |   for (unsigned i = 0; i < 2; ++i) { | 
 | 	  if (i == 1) { | 
 | 		  int *p = 0; | 
 | 		  *p = 0xDEADBEEF; // expected-warning {{dereference}} | 
 | 	  } | 
 |   } | 
 | } | 
 |  | 
 | // Test for a "loop executed 0 times" diagnostic. | 
 | int *radar12322528_bar(); | 
 |  | 
 | void radar12322528_for(int x) { | 
 |   int z; | 
 |   int *p = 0; | 
 |   for (unsigned i = 0; i < x; ++i) { | 
 |     p = radar12322528_bar(); | 
 |   } | 
 |   *p = 0xDEADBEEF; | 
 | } | 
 |  | 
 | void radar12322528_while(int x) { | 
 |   int *p = 0; | 
 |   unsigned i = 0; | 
 |   for ( ; i < x ; ) { | 
 |     ++i; | 
 |     p = radar12322528_bar(); | 
 |   } | 
 |   *p = 0xDEADBEEF; | 
 | } | 
 |  | 
 | void radar12322528_foo_2() { | 
 |   int *p = 0; | 
 |   for (unsigned i = 0; i < 2; ++i) { | 
 |     if (i == 0) | 
 |       continue; | 
 |  | 
 |     if (i == 1) { | 
 |  | 
 |       break; | 
 |     } | 
 |   } | 
 |   *p = 0xDEADBEEF; | 
 | } | 
 |  | 
 | void test_loop_diagnostics() { | 
 |   int *p = 0; | 
 |   for (int i = 0; i < 2; ++i) { p = 0; } | 
 |   *p = 1; | 
 | } | 
 |  | 
 | void test_loop_diagnostics_2() { | 
 |   int *p = 0; | 
 |  | 
 |   for (int i = 0; i < 2; ) { | 
 |  | 
 |     ++i; | 
 |  | 
 |     p = 0; | 
 |  | 
 |   } | 
 |  | 
 |   *p = 1; | 
 | } | 
 |  | 
 | void test_loop_diagnostics_3() { | 
 |   int z; | 
 |   int y; | 
 |   int k; | 
 |   int *p = 0; | 
 |   int i = 0; | 
 |   while (i < 2) { | 
 |     ++i; | 
 |     p = 0; | 
 |   } | 
 |   * p = 1; | 
 | } | 
 |  | 
 | void test_do_while() { | 
 |   unsigned i = 0; | 
 |  | 
 |   int *p; | 
 |  | 
 |   do { | 
 |  | 
 |     ++i; | 
 |     p = 0; | 
 |  | 
 |   } while (i< 2); | 
 |  | 
 |   *p = 0xDEADBEEF; | 
 | } | 
 |  | 
 |  | 
 | void test_logical_and() { | 
 |   int *p = 0; | 
 |   if (1 && 2) { | 
 |     *p = 0xDEADBEEF; | 
 |   } | 
 | } | 
 |  | 
 | void test_logical_or() { | 
 |   int *p = 0; | 
 |   if (0 || 2) { | 
 |     *p = 0xDEADBEEF; | 
 |   } | 
 | } | 
 |  | 
 | void test_logical_or_call() { | 
 |   extern int call(int); | 
 |   int *p = 0; | 
 |   if (call(0 || 2)) { | 
 |     *p = 0xDEADBEEF; | 
 |   } | 
 | } | 
 |  | 
 | void test_nested_logicals(int coin) { | 
 |   int *p = 0; | 
 |  | 
 |   if ((0 || 0) || coin) { | 
 |     *p = 0xDEADBEEF; | 
 |   } | 
 |  | 
 |   if (0 || (0 || !coin)) { | 
 |     *p = 0xDEADBEEF; | 
 |   } | 
 | } | 
 |  | 
 | void test_deeply_nested_logicals() { | 
 |   extern int call(int); | 
 |   int *p = 0; | 
 |  | 
 |   if ((0 || (5 && 0)) ? 0 : ((0 || 4) ? call(1 && 5) : 0)) { | 
 |  | 
 |     *p = 0xDEADBEEF; | 
 |   } | 
 | } | 
 |  | 
 | void test_ternary(int x, int *y) { | 
 |   int z = x ? 0 : 1; | 
 |  | 
 |   int *p = z ? y : 0; | 
 |  | 
 |   *p = 0xDEADBEEF; | 
 | } | 
 |  | 
 | void testUseless(int *y) { | 
 |   if (y) { | 
 |  | 
 |   } | 
 |   if (y) { | 
 |  | 
 |   } | 
 |   int *p = 0; | 
 |   *p = 0xDEADBEEF; | 
 | } | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | // Interprocedural tests. | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | @interface IPA_Foo | 
 | - (int *) returnsPointer; | 
 | @end | 
 |  | 
 | int testFoo(IPA_Foo *x) { | 
 |   if (x) | 
 |     return 1; | 
 |   return *[x returnsPointer]; | 
 | } | 
 |  | 
 | @interface IPA_X : NSObject | 
 | - (int *)getPointer; | 
 | @end | 
 |  | 
 | void test1_IPA_X() { | 
 |   IPA_X *x = nil; | 
 |   *[x getPointer] = 1; // here | 
 | } | 
 |  | 
 |  | 
 | @interface IPA_Y : NSObject | 
 | - (IPA_Y *)opaque; | 
 | - (IPA_X *)getX; | 
 | @end | 
 |  | 
 | @implementation IPA_Y | 
 | - (IPA_X *)getX { | 
 |   return nil; | 
 | } | 
 | @end | 
 |  | 
 | void test_IPA_Y(IPA_Y *y) { | 
 |   if (y) | 
 |     return; | 
 |  | 
 |   IPA_X *x = [[y opaque] getX]; // here | 
 |   *[x getPointer] = 1; | 
 | } | 
 |  | 
 | // From diagnostics/report-issues-within-main-file.cpp: | 
 | void causeDivByZeroInMain(int in) { | 
 |   int m = 0; | 
 |   m = in/m; | 
 |   m++; | 
 | } | 
 |  | 
 | void mainPlusMain() { | 
 |   int i = 0; | 
 |   i++; | 
 |   causeDivByZeroInMain(i); | 
 |   i++; | 
 | } | 
 |  | 
 | // From inlining/path-notes.c: | 
 | int *getZero() { | 
 |   int *p = 0; | 
 |   return p; | 
 | } | 
 |  | 
 | void usePointer(int *p) { | 
 |   *p = 1; | 
 | } | 
 |  | 
 | void testUseOfNullPointer() { | 
 |   // Test the case where an argument expression is itself a call. | 
 |   usePointer(getZero()); | 
 | } | 
 |  | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | // Misc. tests. | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | // Test for tracking null state of ivars. | 
 | @interface RDar12114812 : NSObject  { char *p; } | 
 | @end | 
 | @implementation RDar12114812 | 
 | - (void)test { | 
 |   p = 0; | 
 |   *p = 1; | 
 | } | 
 | @end | 
 |  | 
 | // Test diagnostics for initialization of structs. | 
 | void RDar13295437_f(void *i) __attribute__((__nonnull__)); | 
 | struct RDar13295437_S { int *i; }; | 
 | int  RDar13295437() { | 
 |   struct RDar13295437_S s = {0}; | 
 |   struct RDar13295437_S *sp = &s; | 
 |   RDar13295437_f(sp->i); | 
 |   return 0; | 
 | } | 
 |  | 
 |  | 
 | void testCast(int coin) { | 
 |   if (coin) { | 
 |     (void)(1+2); | 
 |     (void)(2+3); | 
 |     (void)(3+4); | 
 |     *(volatile int *)0 = 1; | 
 |   } | 
 | } | 
 |  | 
 | // The following previously crashed when generating extensive diagnostics. | 
 | @interface RDar10797980_help | 
 | @property (readonly) int x; | 
 | @end | 
 | @interface RDar10797980 : NSObject { | 
 |   RDar10797980_help *y; | 
 | } | 
 | - (void) test; | 
 | @end | 
 | @implementation RDar10797980 | 
 | - (void) test { | 
 |   if (y.x == 1) { | 
 |     int *p = 0; | 
 |     *p = 0xDEADBEEF; // expected-warning {{deference}} | 
 |   } | 
 | } | 
 |  | 
 | // The original source for the above Radar contains another problem: | 
 | // if the end-of-path node is an implicit statement, it may not have a valid | 
 | // source location. | 
 | - (void)test2 { | 
 |   if (bar_cond_assign()) { | 
 |     id foo = [[RDar10797980 alloc] init]; // leak | 
 |   } | 
 |   (void)y; // first statement after the 'if' is an implicit 'self' DeclRefExpr | 
 | } | 
 |  | 
 | @end | 
 |  | 
 | void variousLoops(id input) { | 
 |   extern int a(); | 
 |   extern int b(); | 
 |   extern int c(); | 
 |  | 
 |   extern int work(); | 
 |  | 
 |   while (a()) { | 
 |     work(); | 
 |     work(); | 
 |     work(); | 
 |     *(volatile int *)0 = 1; | 
 |   } | 
 |  | 
 |   int first = 1; | 
 |   do { | 
 |     work(); | 
 |     work(); | 
 |     work(); | 
 |     if (!first) | 
 |       *(volatile int *)0 = 1; | 
 |     first = 0; | 
 |   } while (a()); | 
 |  | 
 |   for (int i = 0; i != b(); ++i) { | 
 |     work(); | 
 |     *(volatile int *)0 = 1; | 
 |   } | 
 |  | 
 |   for (id x in input) { | 
 |     work(); | 
 |     work(); | 
 |     work(); | 
 |     (void)x; | 
 |     *(volatile int *)0 = 1; | 
 |   } | 
 |  | 
 |   int z[] = {1,2}; | 
 |   for (int y : z) { | 
 |     work(); | 
 |     work(); | 
 |     work(); | 
 |     (void)y; | 
 |   } | 
 |  | 
 |   int empty[] = {}; | 
 |   for (int y : empty) { | 
 |     work(); | 
 |     work(); | 
 |     work(); | 
 |     (void)y; | 
 |   } | 
 |  | 
 |   for (int i = 0; ; ++i) { | 
 |     work(); | 
 |     if (i == b()) | 
 |       break; | 
 |   } | 
 |  | 
 |   int i; | 
 |   for (i = 0; i != b(); ++i) { | 
 |     work(); | 
 |     *(volatile int *)0 = 1; | 
 |   } | 
 |  | 
 |   for (; i != b(); ++i) { | 
 |     work(); | 
 |     *(volatile int *)0 = 1; | 
 |   } | 
 |  | 
 |   for (; i != b(); ) { | 
 |     work(); | 
 |     if (i == b()) | 
 |       break; | 
 |     *(volatile int *)0 = 1; | 
 |   } | 
 |  | 
 |   for (;;) { | 
 |     work(); | 
 |     if (i == b()) | 
 |       break; | 
 |   } | 
 |  | 
 |   *(volatile int *)0 = 1; | 
 | } | 
 |  | 
 | void *malloc(unsigned long); | 
 | void *realloc(void *, unsigned long); | 
 | void free(void *); | 
 |  | 
 | void reallocDiagnostics() { | 
 |   char * buf = (char*)malloc(100); | 
 |   char * tmp; | 
 |   tmp = (char*)realloc(buf, 0x1000000); | 
 |   if (!tmp) { | 
 |     return;// expected-warning {{leak}} | 
 |   } | 
 |   buf = tmp; | 
 |   free(buf); | 
 | } | 
 |  | 
 | template <typename T> | 
 | class unique_ptr { | 
 |   T *ptr; | 
 | public: | 
 |   explicit unique_ptr(T *p) : ptr(p) {} | 
 |   ~unique_ptr() { delete ptr; } | 
 | }; | 
 |  | 
 | void test() { | 
 |   int i = 0; | 
 |   ++i; | 
 |  | 
 |   unique_ptr<int> p(new int[4]); | 
 |   { | 
 |     ++i; | 
 |   } | 
 | } | 
 |  | 
 | void longLines() { | 
 |   id foo = [[NSObject alloc] init]; // leak | 
 |   id bar = | 
 |            [foo retain]; | 
 |   [bar release]; | 
 |   id baz = [foo | 
 |               retain]; | 
 |   [baz release]; | 
 |   // This next line is intentionally longer than 80 characters. | 
 |   id garply = [foo                                                              retain]; | 
 |   [garply release]; | 
 | } | 
 |  | 
 | #define POINTER(T) T* | 
 | POINTER(void) testMacroInFunctionDecl(void *q) { | 
 |   int *p = 0; | 
 |   *p = 1; | 
 |   return q; | 
 | } | 
 |  | 
 | namespace rdar14960554 { | 
 |   class Foo { | 
 |     int a = 1; | 
 |     int b = 2; | 
 |     int c = 3; | 
 |  | 
 |     Foo() : | 
 |       a(0), | 
 |       c(3) { | 
 |       // Check that we don't have an edge to the in-class initializer for 'b'. | 
 |       if (b == 2) | 
 |         *(volatile int *)0 = 1; | 
 |     } | 
 |   }; | 
 | } | 
 |  |