1 // RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config suppress-inlined-defensive-checks=true -verify %s 2 3 typedef signed char BOOL; 4 typedef struct objc_class *Class; 5 typedef struct objc_object { 6 Class isa; 7 } *id; 8 @protocol NSObject - (BOOL)isEqual:(id)object; @end 9 @interface NSObject <NSObject> {} 10 +(id)alloc; 11 +(id)new; 12 -(id)init; 13 -(id)autorelease; 14 -(id)copy; 15 - (Class)class; 16 -(id)retain; 17 @end 18 19 // Check that inline defensive checks is triggered for null expressions 20 // within CompoundLiteralExpr. 21 typedef union { 22 struct dispatch_object_s *_do; 23 struct dispatch_source_s *_ds; 24 } dispatch_object_t __attribute__((__transparent_union__)); 25 typedef struct dispatch_source_s *dispatch_source_t; 26 27 extern __attribute__((visibility("default"))) __attribute__((__nonnull__)) __attribute__((__nothrow__)) 28 void 29 dispatch_resume(dispatch_object_t object); 30 31 @interface AppDelegate : NSObject { 32 @protected 33 dispatch_source_t p; 34 } 35 @end 36 @implementation AppDelegate 37 - (void)updateDeleteTimer { 38 if (p != ((void*)0)) 39 ; 40 } 41 - (void)createAndStartDeleteTimer { 42 [self updateDeleteTimer]; 43 dispatch_resume(p); // no warning 44 } 45 @end 46 47 // Test nil receiver suppression. 48 // We only suppress on nil receiver if the nil value is directly causing the bug. 49 @interface Foo { 50 @public 51 int x; 52 } 53 - (Foo *)getFooPtr; 54 @end 55 56 Foo *retNil() { 57 return 0; 58 } 59 60 Foo *retInputOrNil(Foo *p) { 61 if (p) 62 return p; 63 return 0; 64 } 65 66 void idc(Foo *p) { 67 if (p) 68 ; 69 } 70 71 int testNilReceiver(Foo* fPtr) { 72 if (fPtr) 73 ; 74 // On a path where fPtr is nil, mem should be nil. 75 Foo *mem = [fPtr getFooPtr]; 76 return mem->x; // expected-warning {{Access to instance variable 'x' results in a dereference of a null pointer}} 77 } 78 79 int suppressNilReceiverRetNullCond(Foo* fPtr) { 80 unsigned zero = 0; 81 fPtr = retInputOrNil(fPtr); 82 // On a path where fPtr is nzil, mem should be nil. 83 Foo *mem = [fPtr getFooPtr]; 84 return mem->x; 85 } 86 87 int suppressNilReceiverRetNullCondCast(id fPtr) { 88 unsigned zero = 0; 89 fPtr = retInputOrNil(fPtr); 90 // On a path where fPtr is nzil, mem should be nil. 91 Foo *mem = ((id)([(Foo*)(fPtr) getFooPtr])); 92 return mem->x; 93 } 94 95 int dontSuppressNilReceiverRetNullCond(Foo* fPtr) { 96 unsigned zero = 0; 97 fPtr = retInputOrNil(fPtr); 98 // On a path where fPtr is nil, mem should be nil. 99 // The warning is not suppressed because the receiver being nil is not 100 // directly related to the value that triggers the warning. 101 Foo *mem = [fPtr getFooPtr]; 102 if (!mem) 103 return 5/zero; // expected-warning {{Division by zero}} 104 return 0; 105 } 106 107 int dontSuppressNilReceiverRetNull(Foo* fPtr) { 108 unsigned zero = 0; 109 fPtr = retNil(); 110 // On a path where fPtr is nil, mem should be nil. 111 // The warning is not suppressed because the receiver being nil is not 112 // directly related to the value that triggers the warning. 113 Foo *mem = [fPtr getFooPtr]; 114 if (!mem) 115 return 5/zero; // expected-warning {{Division by zero}} 116 return 0; 117 } 118 119 int dontSuppressNilReceiverIDC(Foo* fPtr) { 120 unsigned zero = 0; 121 idc(fPtr); 122 // On a path where fPtr is nil, mem should be nil. 123 // The warning is not suppressed because the receiver being nil is not 124 // directly related to the value that triggers the warning. 125 Foo *mem = [fPtr getFooPtr]; 126 if (!mem) 127 return 5/zero; // expected-warning {{Division by zero}} 128 return 0; 129 } 130