130 lines · plain
1// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config suppress-inlined-defensive-checks=true -verify %s2 3typedef signed char BOOL;4typedef struct objc_class *Class;5typedef struct objc_object {6 Class isa;7} *id;8@protocol NSObject - (BOOL)isEqual:(id)object; @end9@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@end18 19// Check that inline defensive checks is triggered for null expressions20// within CompoundLiteralExpr.21typedef union {22 struct dispatch_object_s *_do;23 struct dispatch_source_s *_ds;24} dispatch_object_t __attribute__((__transparent_union__));25typedef struct dispatch_source_s *dispatch_source_t;26 27extern __attribute__((visibility("default"))) __attribute__((__nonnull__)) __attribute__((__nothrow__))28void29dispatch_resume(dispatch_object_t object);30 31@interface AppDelegate : NSObject {32@protected33 dispatch_source_t p;34}35@end36@implementation AppDelegate37- (void)updateDeleteTimer {38 if (p != ((void*)0))39 ;40}41- (void)createAndStartDeleteTimer {42 [self updateDeleteTimer];43 dispatch_resume(p); // no warning44}45@end46 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@public51 int x;52}53- (Foo *)getFooPtr;54@end55 56Foo *retNil(void) {57 return 0;58}59 60Foo *retInputOrNil(Foo *p) {61 if (p)62 return p;63 return 0;64}65 66void idc(Foo *p) {67 if (p)68 ;69}70 71int 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 79int 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 87int 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 95int 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 not100 // 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 107int 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 not112 // 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 119int 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 not124 // 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