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