// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config suppress-inlined-defensive-checks=true -verify %s typedef signed char BOOL; typedef struct objc_class *Class; typedef struct objc_object { Class isa; } *id; @protocol NSObject - (BOOL)isEqual:(id)object; @end @interface NSObject {} +(id)alloc; +(id)new; -(id)init; -(id)autorelease; -(id)copy; - (Class)class; -(id)retain; @end // Check that inline defensive checks is triggered for null expressions // within CompoundLiteralExpr. typedef union { struct dispatch_object_s *_do; struct dispatch_source_s *_ds; } dispatch_object_t __attribute__((__transparent_union__)); typedef struct dispatch_source_s *dispatch_source_t; extern __attribute__((visibility("default"))) __attribute__((__nonnull__)) __attribute__((__nothrow__)) void dispatch_resume(dispatch_object_t object); @interface AppDelegate : NSObject { @protected dispatch_source_t p; } @end @implementation AppDelegate - (void)updateDeleteTimer { if (p != ((void*)0)) ; } - (void)createAndStartDeleteTimer { [self updateDeleteTimer]; dispatch_resume(p); // no warning } @end // Test nil receiver suppression. // We only suppress on nil receiver if the nil value is directly causing the bug. @interface Foo { @public int x; } - (Foo *)getFooPtr; @end Foo *retNil() { return 0; } Foo *retInputOrNil(Foo *p) { if (p) return p; return 0; } void idc(Foo *p) { if (p) ; } int testNilReceiver(Foo* fPtr) { if (fPtr) ; // On a path where fPtr is nil, mem should be nil. Foo *mem = [fPtr getFooPtr]; return mem->x; // expected-warning {{Access to instance variable 'x' results in a dereference of a null pointer}} } int suppressNilReceiverRetNullCond(Foo* fPtr) { unsigned zero = 0; fPtr = retInputOrNil(fPtr); // On a path where fPtr is nzil, mem should be nil. Foo *mem = [fPtr getFooPtr]; return mem->x; } int suppressNilReceiverRetNullCondCast(id fPtr) { unsigned zero = 0; fPtr = retInputOrNil(fPtr); // On a path where fPtr is nzil, mem should be nil. Foo *mem = ((id)([(Foo*)(fPtr) getFooPtr])); return mem->x; } int dontSuppressNilReceiverRetNullCond(Foo* fPtr) { unsigned zero = 0; fPtr = retInputOrNil(fPtr); // On a path where fPtr is nil, mem should be nil. // The warning is not suppressed because the receiver being nil is not // directly related to the value that triggers the warning. Foo *mem = [fPtr getFooPtr]; if (!mem) return 5/zero; // expected-warning {{Division by zero}} return 0; } int dontSuppressNilReceiverRetNull(Foo* fPtr) { unsigned zero = 0; fPtr = retNil(); // On a path where fPtr is nil, mem should be nil. // The warning is not suppressed because the receiver being nil is not // directly related to the value that triggers the warning. Foo *mem = [fPtr getFooPtr]; if (!mem) return 5/zero; // expected-warning {{Division by zero}} return 0; } int dontSuppressNilReceiverIDC(Foo* fPtr) { unsigned zero = 0; idc(fPtr); // On a path where fPtr is nil, mem should be nil. // The warning is not suppressed because the receiver being nil is not // directly related to the value that triggers the warning. Foo *mem = [fPtr getFooPtr]; if (!mem) return 5/zero; // expected-warning {{Division by zero}} return 0; }