|  | // RUN: %clang_analyze_cc1 -fobjc-arc -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull -DNOSYSTEMHEADERS=0 -verify %s | 
|  | // RUN: %clang_analyze_cc1 -fobjc-arc -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull -analyzer-config nullability:NoDiagnoseCallsToSystemHeaders=true -DNOSYSTEMHEADERS=1 -verify %s | 
|  |  | 
|  | #include "Inputs/system-header-simulator-for-nullability.h" | 
|  |  | 
|  | int getRandom(); | 
|  |  | 
|  | typedef struct Dummy { int val; } Dummy; | 
|  |  | 
|  | void takesNullable(Dummy *_Nullable); | 
|  | void takesNonnull(Dummy *_Nonnull); | 
|  | Dummy *_Nullable returnsNullable(); | 
|  |  | 
|  | void testBasicRules() { | 
|  | // The tracking of nullable values is turned off. | 
|  | Dummy *p = returnsNullable(); | 
|  | takesNonnull(p); // no warning | 
|  | Dummy *q = 0; | 
|  | if (getRandom()) { | 
|  | takesNullable(q); | 
|  | takesNonnull(q); // expected-warning {{Null passed to a callee that requires a non-null 1st parameter}} | 
|  | } | 
|  | } | 
|  |  | 
|  | Dummy *_Nonnull testNullReturn() { | 
|  | Dummy *p = 0; | 
|  | return p; // expected-warning {{Null returned from a function that is expected to return a non-null value}} | 
|  | } | 
|  |  | 
|  | void onlyReportFirstPreconditionViolationOnPath() { | 
|  | Dummy *p = 0; | 
|  | takesNonnull(p); // expected-warning {{Null passed to a callee that requires a non-null 1st parameter}} | 
|  | takesNonnull(p); // No warning. | 
|  | // Passing null to nonnull is a sink. Stop the analysis. | 
|  | int i = 0; | 
|  | i = 5 / i; // no warning | 
|  | (void)i; | 
|  | } | 
|  |  | 
|  | Dummy *_Nonnull doNotWarnWhenPreconditionIsViolatedInTopFunc( | 
|  | Dummy *_Nonnull p) { | 
|  | if (!p) { | 
|  | Dummy *ret = | 
|  | 0; // avoid compiler warning (which is not generated by the analyzer) | 
|  | if (getRandom()) | 
|  | return ret; // no warning | 
|  | else | 
|  | return p; // no warning | 
|  | } else { | 
|  | return p; | 
|  | } | 
|  | } | 
|  |  | 
|  | Dummy *_Nonnull doNotWarnWhenPreconditionIsViolated(Dummy *_Nonnull p) { | 
|  | if (!p) { | 
|  | Dummy *ret = | 
|  | 0; // avoid compiler warning (which is not generated by the analyzer) | 
|  | if (getRandom()) | 
|  | return ret; // no warning | 
|  | else | 
|  | return p; // no warning | 
|  | } else { | 
|  | return p; | 
|  | } | 
|  | } | 
|  |  | 
|  | void testPreconditionViolationInInlinedFunction(Dummy *p) { | 
|  | doNotWarnWhenPreconditionIsViolated(p); | 
|  | } | 
|  |  | 
|  | void inlinedNullable(Dummy *_Nullable p) { | 
|  | if (p) return; | 
|  | } | 
|  | void inlinedNonnull(Dummy *_Nonnull p) { | 
|  | if (p) return; | 
|  | } | 
|  | void inlinedUnspecified(Dummy *p) { | 
|  | if (p) return; | 
|  | } | 
|  |  | 
|  | Dummy *_Nonnull testDefensiveInlineChecks(Dummy * p) { | 
|  | switch (getRandom()) { | 
|  | case 1: inlinedNullable(p); break; | 
|  | case 2: inlinedNonnull(p); break; | 
|  | case 3: inlinedUnspecified(p); break; | 
|  | } | 
|  | if (getRandom()) | 
|  | takesNonnull(p); | 
|  | return p; | 
|  | } | 
|  |  | 
|  | @interface TestObject : NSObject | 
|  | @end | 
|  |  | 
|  | TestObject *_Nonnull getNonnullTestObject(); | 
|  |  | 
|  | void testObjCARCImplicitZeroInitialization() { | 
|  | TestObject * _Nonnull implicitlyZeroInitialized; // no-warning | 
|  | implicitlyZeroInitialized = getNonnullTestObject(); | 
|  | } | 
|  |  | 
|  | void testObjCARCExplicitZeroInitialization() { | 
|  | TestObject * _Nonnull explicitlyZeroInitialized = nil; // expected-warning {{nil assigned to a pointer which is expected to have non-null value}} | 
|  | } | 
|  |  | 
|  | // Under ARC, returned expressions of ObjC objects types are are implicitly | 
|  | // cast to _Nonnull when the functions return type is _Nonnull, so make | 
|  | // sure this doesn't implicit cast doesn't suppress a legitimate warning. | 
|  | 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() { | 
|  | return nil; // expected-warning {{nil returned from a function that is expected to return a non-null value}} | 
|  | } | 
|  |  | 
|  | TestObject * _Nonnull returnsNilObjCInstanceDirectlyWithSuppressingCast() { | 
|  | return (TestObject * _Nonnull)nil; // no-warning | 
|  | } | 
|  |  | 
|  | @interface SomeClass : NSObject | 
|  | @end | 
|  |  | 
|  | @implementation SomeClass (MethodReturn) | 
|  | - (SomeClass * _Nonnull)testReturnsNilInNonnull { | 
|  | SomeClass *local = nil; | 
|  | return local; // expected-warning {{nil returned from a method that is expected to return a non-null value}} | 
|  | } | 
|  |  | 
|  | - (SomeClass * _Nonnull)testReturnsCastSuppressedNilInNonnull { | 
|  | SomeClass *local = nil; | 
|  | return (SomeClass * _Nonnull)local; // no-warning | 
|  | } | 
|  |  | 
|  | - (SomeClass * _Nonnull)testReturnsNilInNonnullWhenPreconditionViolated:(SomeClass * _Nonnull) p { | 
|  | SomeClass *local = nil; | 
|  | if (!p) // Pre-condition violated here. | 
|  | return local; // no-warning | 
|  | else | 
|  | return p; // no-warning | 
|  | } | 
|  | @end | 
|  |  | 
|  |  | 
|  | void callFunctionInSystemHeader() { | 
|  | NSString *s; | 
|  | s = nil; | 
|  |  | 
|  | NSSystemFunctionTakingNonnull(s); | 
|  | #if !NOSYSTEMHEADERS | 
|  | // expected-warning@-2{{nil passed to a callee that requires a non-null 1st parameter}} | 
|  | #endif | 
|  | } | 
|  |  | 
|  | void callMethodInSystemHeader() { | 
|  | NSString *s; | 
|  | s = nil; | 
|  |  | 
|  | NSSystemClass *sc = [[NSSystemClass alloc] init]; | 
|  | [sc takesNonnull:s]; | 
|  | #if !NOSYSTEMHEADERS | 
|  | // expected-warning@-2{{nil passed to a callee that requires a non-null 1st parameter}} | 
|  | #endif | 
|  | } |