// 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 @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