|  | // RUN: %clang_analyze_cc1 -analyzer-checker=core,nullability -verify %s | 
|  |  | 
|  | #define nil 0 | 
|  |  | 
|  | @protocol NSObject | 
|  | + (id)alloc; | 
|  | - (id)init; | 
|  | - (instancetype)autorelease; | 
|  | - (void)release; | 
|  | @end | 
|  |  | 
|  | __attribute__((objc_root_class)) | 
|  | @interface | 
|  | NSObject<NSObject> | 
|  | @end | 
|  |  | 
|  | @interface TestObject : NSObject | 
|  | @end | 
|  |  | 
|  | TestObject *_Nonnull returnsNilObjCInstanceIndirectly() { | 
|  | TestObject *local = nil; | 
|  | return local; // expected-warning {{nil returned from a function that is expected to return a non-null value}} | 
|  | } | 
|  |  | 
|  | TestObject * _Nonnull returnsNilObjCInstanceIndirectlyWithSupressingCast() { | 
|  | TestObject *local = nil; | 
|  | return (TestObject * _Nonnull)local; // no-warning | 
|  | } | 
|  |  | 
|  | TestObject * _Nonnull returnsNilObjCInstanceDirectly() { | 
|  | // The first warning is from Sema. The second is from the static analyzer. | 
|  | return nil; // expected-warning {{null returned from function that requires a non-null return value}} | 
|  | // expected-warning@-1 {{nil returned from a function that is expected to return a non-null value}} | 
|  | } | 
|  |  | 
|  | TestObject * _Nonnull returnsNilObjCInstanceDirectlyWithSuppressingCast() { | 
|  | return (TestObject * _Nonnull)nil; // no-warning | 
|  | } | 
|  |  | 
|  | void testObjCNonARCNoInitialization(TestObject * _Nonnull p) { | 
|  | TestObject * _Nonnull implicitlyZeroInitialized; // no-warning | 
|  | implicitlyZeroInitialized = p; | 
|  | } | 
|  |  | 
|  | void testObjCNonARCExplicitZeroInitialization() { | 
|  | TestObject * _Nonnull explicitlyZeroInitialized = nil; // expected-warning {{nil assigned to a pointer which is expected to have non-null value}} | 
|  | } | 
|  |  | 
|  | @interface ClassWithInitializers : NSObject | 
|  | @end | 
|  |  | 
|  | @implementation ClassWithInitializers | 
|  | - (instancetype _Nonnull)initWithNonnullReturnAndSelfCheckingIdiom { | 
|  | // This defensive check is a common-enough idiom that we don't want | 
|  | // to issue a diagnostic for it. | 
|  | if (self = [super init]) { | 
|  | } | 
|  |  | 
|  | return self; // no-warning | 
|  | } | 
|  |  | 
|  | - (instancetype _Nonnull)initWithNonnullReturnAndNilReturnViaLocal { | 
|  | self = [super init]; | 
|  | // This leaks, but we're not checking for that here. | 
|  |  | 
|  | ClassWithInitializers *other = nil; | 
|  | // False negative. Once we have more subtle suppression of defensive checks in | 
|  | // initializers we should warn here. | 
|  | return other; | 
|  | } | 
|  |  | 
|  | - (instancetype _Nonnull)initWithPreconditionViolation:(int)p { | 
|  | self = [super init]; | 
|  | if (p < 0) { | 
|  | [self release]; | 
|  | return (ClassWithInitializers * _Nonnull)nil; | 
|  | } | 
|  | return self; | 
|  | } | 
|  |  | 
|  | + (instancetype _Nonnull)factoryCallingInitWithNonnullReturnAndSelfCheckingIdiom { | 
|  | return [[[self alloc] initWithNonnullReturnAndSelfCheckingIdiom] autorelease]; // no-warning | 
|  | } | 
|  |  | 
|  | + (instancetype _Nonnull)factoryCallingInitWithNonnullReturnAndNilReturnViaLocal { | 
|  | return [[[self alloc] initWithNonnullReturnAndNilReturnViaLocal] autorelease]; // no-warning | 
|  | } | 
|  |  | 
|  | + (instancetype _Nonnull)initWithPreconditionViolation:(int) p { | 
|  | return [[[self alloc] initWithPreconditionViolation:p] autorelease]; // no-warning | 
|  | } | 
|  |  | 
|  | - (TestObject * _Nonnull) returnsNil { | 
|  | return (TestObject * _Nonnull)nil; | 
|  | } | 
|  | - (TestObject * _Nonnull) inlineOfReturnsNilObjCInstanceDirectlyWithSuppressingCast { | 
|  | TestObject *o = [self returnsNil]; | 
|  | return o; | 
|  | } | 
|  | @end |