Home | History | Annotate | Download | only in Analysis
      1 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core -analyzer-checker=deadcode -analyzer-store=region -verify -fblocks  -analyzer-opt-analyze-nested-blocks -fobjc-nonfragile-abi -fobjc-arc %s
      2 
      3 typedef signed char BOOL;
      4 typedef struct _NSZone NSZone;
      5 @class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
      6 
      7 @protocol NSObject
      8 - (BOOL)isEqual:(id)object;
      9 @end
     10 @protocol NSCopying
     11 - (id)copyWithZone:(NSZone *)zone;
     12 @end
     13 @protocol NSCoding
     14 - (void)encodeWithCoder:(NSCoder *)aCoder;
     15 @end
     16 @interface NSObject <NSObject> {}
     17 + (id)alloc;
     18 @end
     19 typedef const struct __CFAllocator * CFAllocatorRef;
     20 extern const CFAllocatorRef kCFAllocatorDefault;
     21 typedef double CFTimeInterval;
     22 typedef CFTimeInterval CFAbsoluteTime;
     23 extern CFAbsoluteTime CFAbsoluteTimeGetCurrent(void);
     24 typedef const struct __CFDate * CFDateRef;
     25 extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at);
     26 
     27 typedef const void* objc_objectptr_t;
     28 __attribute__((ns_returns_retained)) id objc_retainedObject(objc_objectptr_t __attribute__((cf_consumed)) pointer);
     29 __attribute__((ns_returns_not_retained)) id objc_unretainedObject(objc_objectptr_t pointer);
     30 
     31 // Test the analyzer is working at all.
     32 void test_working() {
     33   int *p = 0;
     34   *p = 0xDEADBEEF; // expected-warning {{null}}
     35 }
     36 
     37 // Test that in ARC mode that blocks are correctly automatically copied
     38 // and not flagged as warnings by the analyzer.
     39 typedef void (^Block)(void);
     40 void testblock_bar(int x);
     41 
     42 Block testblock_foo(int x) {
     43   Block b = ^{ testblock_bar(x); };
     44   return b; // no-warning
     45 }
     46 
     47 Block testblock_baz(int x) {
     48   return ^{ testblock_bar(x); }; // no-warning
     49 }
     50 
     51 Block global_block;
     52 
     53 void testblock_qux(int x) {
     54   global_block = ^{ testblock_bar(x); }; // no-warning
     55 }
     56 
     57 // Test that Objective-C pointers are null initialized.
     58 void test_nil_initialized() {
     59   id x;
     60   if (x == 0)
     61     return;
     62   int *p = 0;
     63   *p = 0xDEADBEEF; // no-warning
     64 }
     65 
     66 // Test that we don't flag leaks of Objective-C objects.
     67 void test_alloc() {
     68   [NSObject alloc]; // no-warning
     69 }
     70 
     71 // Test that CF allocations are still caught as leaks.
     72 void test_cf_leak() {
     73   CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
     74   CFDateRef date = CFDateCreate(0, t); // expected-warning {{Potential leak}}
     75   (void) date;
     76 }
     77 
     78 // Test that 'init' methods do not try to claim ownerhip of an *unowned* allocated object
     79 // in ARC mode.
     80 @interface RDar9424890_A :  NSObject
     81 - (id)initWithCleaner:(int)pop mop:(NSString *)mop ;
     82 - (RDar9424890_A *)rdar9424890:(NSString *)identifier;
     83 @end
     84 @interface RDar9424890_B : NSObject
     85 @end
     86 @implementation RDar9424890_B
     87 - (RDar9424890_A *)obj:(RDar9424890_A *)obj {
     88   static NSString *WhizFiz = @"WhizFiz";
     89   RDar9424890_A *cell = [obj rdar9424890:WhizFiz];
     90   if (cell == ((void*)0)) {
     91     cell = [[RDar9424890_A alloc] initWithCleaner:0 mop:WhizFiz]; // no-warning
     92   }
     93   return cell;
     94 }
     95 @end
     96 
     97 // Test that dead store checking works in the prescence of "cleanups" in the AST.
     98 void rdar9424882() {
     99   id x = [NSObject alloc]; // expected-warning {{Value stored to 'x' during its initialization is never read}}
    100 }
    101 
    102 // Test 
    103 typedef const void *CFTypeRef;
    104 typedef const struct __CFString *CFStringRef;
    105 
    106 @interface NSString
    107 - (id) self;
    108 @end
    109 
    110 CFTypeRef CFCreateSomething();
    111 CFStringRef CFCreateString();
    112 CFTypeRef CFGetSomething();
    113 CFStringRef CFGetString();
    114 
    115 id CreateSomething();
    116 NSString *CreateNSString();
    117 
    118 void from_cf() {
    119   id obj1 = (__bridge_transfer id)CFCreateSomething(); // expected-warning{{never read}}
    120   id obj2 = (__bridge_transfer NSString*)CFCreateString();
    121   [obj2 self]; // Add a use, to show we can use the object after it has been transfered.
    122   id obj3 = (__bridge id)CFGetSomething();
    123   [obj3 self]; // Add a use, to show we can use the object after it has been bridged.
    124   id obj4 = (__bridge NSString*)CFGetString(); // expected-warning{{never read}}
    125   id obj5 = (__bridge id)CFCreateSomething(); // expected-warning{{never read}} expected-warning{{leak}}
    126   id obj6 = (__bridge NSString*)CFCreateString(); // expected-warning{{never read}} expected-warning{{leak}}
    127 }
    128 
    129 void to_cf(id obj) {
    130   CFTypeRef cf1 = (__bridge_retained CFTypeRef)CreateSomething(); // expected-warning{{never read}}
    131   CFStringRef cf2 = (__bridge_retained CFStringRef)CreateNSString(); // expected-warning{{never read}}
    132   CFTypeRef cf3 = (__bridge CFTypeRef)CreateSomething(); // expected-warning{{never read}}
    133   CFStringRef cf4 = (__bridge CFStringRef)CreateNSString();  // expected-warning{{never read}}
    134 }
    135 
    136 void test_objc_retainedObject() {
    137   CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
    138   CFDateRef date = CFDateCreate(0, t);
    139   id x = objc_retainedObject(date);
    140   (void) x;
    141 }
    142 
    143 void test_objc_unretainedObject() {
    144   CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
    145   CFDateRef date = CFDateCreate(0, t);  // expected-warning {{Potential leak}}
    146   id x = objc_unretainedObject(date);
    147   (void) x;
    148 }
    149 
    150