// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config suppress-null-return-paths=false -verify %s // RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -DSUPPRESSED=1 %s // RUN: %clang_cc1 -analyze -analyzer-checker=core -fobjc-arc -verify -DSUPPRESSED=1 %s // RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config avoid-suppressing-null-argument-paths=true -DSUPPRESSED=1 -DNULL_ARGS=1 -verify %s #define ARC __has_feature(objc_arc) #if defined(SUPPRESSED) && !ARC // expected-no-diagnostics #endif @interface PointerWrapper - (int *)getPtr; - (id)getObject; @end id getNil() { return 0; } void testNilReceiverHelperA(int *x) { *x = 1; #ifndef SUPPRESSED // expected-warning@-2 {{Dereference of null pointer}} #endif } void testNilReceiverHelperB(int *x) { *x = 1; // FIXME: Suppression for this case isn't working under ARC. It should. #if !defined(SUPPRESSED) || (defined(SUPPRESSED) && ARC) // expected-warning@-3 {{Dereference of null pointer}} #endif } void testNilReceiver(int coin) { id x = getNil(); if (coin) testNilReceiverHelperA([x getPtr]); else testNilReceiverHelperB([[x getObject] getPtr]); } // FALSE NEGATIVES (over-suppression) __attribute__((objc_root_class)) @interface SomeClass { int ivar; } -(int *)methodReturningNull; @property(readonly) int *propertyReturningNull; @property(readonly) int *synthesizedProperty; @property(readonly) SomeClass *propertyReturningNil; @end @interface SubOfSomeClass : SomeClass @end @implementation SubOfSomeClass @end @implementation SomeClass -(int *)methodReturningNull { return 0; } -(int *)propertyReturningNull { return 0; } -(SomeClass *)propertyReturningNil { return 0; } +(int *)classPropertyReturningNull { return 0; } @end void testMethodReturningNull(SomeClass *sc) { int *result = [sc methodReturningNull]; *result = 1; #ifndef SUPPRESSED // expected-warning@-2 {{Dereference of null pointer}} #endif } void testPropertyReturningNull(SomeClass *sc) { int *result = sc.propertyReturningNull; *result = 1; #ifndef SUPPRESSED // expected-warning@-2 {{Dereference of null pointer}} #endif } @implementation SubOfSomeClass (ForTestOfSuperProperty) -(void)testSuperPropertyReturningNull { int *result = super.propertyReturningNull; *result = 1; #ifndef SUPPRESSED // expected-warning@-2 {{Dereference of null pointer}} #endif } @end void testClassPropertyReturningNull() { int *result = SomeClass.classPropertyReturningNull; *result = 1; #ifndef SUPPRESSED // expected-warning@-2 {{Dereference of null pointer}} #endif } @implementation SomeClass (ForTestOfPropertyReturningNil) void testPropertyReturningNil(SomeClass *sc) { SomeClass *result = sc.propertyReturningNil; result->ivar = 1; #ifndef SUPPRESSED // expected-warning@-2 {{Access to instance variable 'ivar' results in a dereference of a null pointer (loaded from variable 'result')}} #endif } @end void testSynthesizedPropertyReturningNull(SomeClass *sc) { if (sc.synthesizedProperty) return; int *result = sc.synthesizedProperty; *result = 1; #ifndef SUPPRESSED // expected-warning@-2 {{Dereference of null pointer}} #endif }