1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,nullability -verify %s 2 3 #define nil 0 4 5 @protocol NSObject 6 + (id)alloc; 7 - (id)init; 8 - (instancetype)autorelease; 9 - (void)release; 10 @end 11 12 __attribute__((objc_root_class)) 13 @interface 14 NSObject<NSObject> 15 @end 16 17 @interface TestObject : NSObject 18 @end 19 20 TestObject * _Nonnull returnsNilObjCInstanceIndirectly() { 21 TestObject *local = 0; 22 return local; // expected-warning {{Null is returned from a function that is expected to return a non-null value}} 23 } 24 25 TestObject * _Nonnull returnsNilObjCInstanceIndirectlyWithSupressingCast() { 26 TestObject *local = 0; 27 return (TestObject * _Nonnull)local; // no-warning 28 } 29 30 TestObject * _Nonnull returnsNilObjCInstanceDirectly() { 31 // The first warning is from Sema. The second is from the static analyzer. 32 return nil; // expected-warning {{null returned from function that requires a non-null return value}} 33 // expected-warning@-1 {{Null is returned from a function that is expected to return a non-null value}} 34 } 35 36 TestObject * _Nonnull returnsNilObjCInstanceDirectlyWithSuppressingCast() { 37 return (TestObject * _Nonnull)nil; // no-warning 38 } 39 40 void testObjCNonARCNoInitialization(TestObject * _Nonnull p) { 41 TestObject * _Nonnull implicitlyZeroInitialized; // no-warning 42 implicitlyZeroInitialized = p; 43 } 44 45 void testObjCNonARCExplicitZeroInitialization() { 46 TestObject * _Nonnull explicitlyZeroInitialized = nil; // expected-warning {{Null is assigned to a pointer which is expected to have non-null value}} 47 } 48 49 @interface ClassWithInitializers : NSObject 50 @end 51 52 @implementation ClassWithInitializers 53 - (instancetype _Nonnull)initWithNonnullReturnAndSelfCheckingIdiom { 54 // This defensive check is a common-enough idiom that we don't want 55 // to issue a diagnostic for it. 56 if (self = [super init]) { 57 } 58 59 return self; // no-warning 60 } 61 62 - (instancetype _Nonnull)initWithNonnullReturnAndNilReturnViaLocal { 63 self = [super init]; 64 // This leaks, but we're not checking for that here. 65 66 ClassWithInitializers *other = nil; 67 // False negative. Once we have more subtle suppression of defensive checks in 68 // initializers we should warn here. 69 return other; 70 } 71 72 - (instancetype _Nonnull)initWithPreconditionViolation:(int)p { 73 self = [super init]; 74 if (p < 0) { 75 [self release]; 76 return (ClassWithInitializers * _Nonnull)nil; 77 } 78 return self; 79 } 80 81 + (instancetype _Nonnull)factoryCallingInitWithNonnullReturnAndSelfCheckingIdiom { 82 return [[[self alloc] initWithNonnullReturnAndSelfCheckingIdiom] autorelease]; // no-warning 83 } 84 85 + (instancetype _Nonnull)factoryCallingInitWithNonnullReturnAndNilReturnViaLocal { 86 return [[[self alloc] initWithNonnullReturnAndNilReturnViaLocal] autorelease]; // no-warning 87 } 88 89 + (instancetype _Nonnull)initWithPreconditionViolation:(int) p { 90 return [[[self alloc] initWithPreconditionViolation:p] autorelease]; // no-warning 91 } 92 93 - (TestObject * _Nonnull) returnsNil { 94 return (TestObject * _Nonnull)nil; 95 } 96 - (TestObject * _Nonnull) inlineOfReturnsNilObjCInstanceDirectlyWithSuppressingCast { 97 TestObject *o = [self returnsNil]; 98 return o; 99 } 100 @end 101