| // RUN: %clang_analyze_cc1 -fblocks -verify %s -analyzer-checker=core \ | 
 | // RUN:   -analyzer-checker=nullability.NullPassedToNonnull \ | 
 | // RUN:   -analyzer-checker=nullability.NullReturnedFromNonnull \ | 
 | // RUN:   -analyzer-checker=nullability.NullablePassedToNonnull \ | 
 | // RUN:   -analyzer-checker=nullability.NullableReturnedFromNonnull \ | 
 | // RUN:   -analyzer-checker=nullability.NullableDereferenced \ | 
 | // RUN:   -DNOSYSTEMHEADERS=0 | 
 |  | 
 | // RUN: %clang_analyze_cc1 -fblocks -verify %s -analyzer-checker=core \ | 
 | // RUN:   -analyzer-checker=nullability.NullPassedToNonnull \ | 
 | // RUN:   -analyzer-checker=nullability.NullReturnedFromNonnull \ | 
 | // RUN:   -analyzer-checker=nullability.NullablePassedToNonnull \ | 
 | // RUN:   -analyzer-checker=nullability.NullableReturnedFromNonnull \ | 
 | // RUN:   -analyzer-checker=nullability.NullableDereferenced \ | 
 | // RUN:   -DNOSYSTEMHEADERS=1 \ | 
 | // RUN:   -analyzer-config nullability:NoDiagnoseCallsToSystemHeaders=true | 
 |  | 
 | // RUN: %clang_analyze_cc1 -fblocks -verify %s -analyzer-checker=core\ | 
 | // RUN:   -analyzer-checker=nullability.NullPassedToNonnull\ | 
 | // RUN:   -analyzer-checker=nullability.NullReturnedFromNonnull\ | 
 | // RUN:   -analyzer-checker=nullability.NullablePassedToNonnull\ | 
 | // RUN:   -analyzer-checker=nullability.NullableReturnedFromNonnull\ | 
 | // RUN:   -analyzer-checker=nullability.NullableDereferenced\ | 
 | // RUN:   -DNOSYSTEMHEADERS=0 -fobjc-arc | 
 |  | 
 | // RUN: %clang_analyze_cc1 -fblocks -verify %s -analyzer-checker=core\ | 
 | // RUN:   -analyzer-checker=nullability.NullPassedToNonnull\ | 
 | // RUN:   -analyzer-checker=nullability.NullReturnedFromNonnull\ | 
 | // RUN:   -analyzer-checker=nullability.NullablePassedToNonnull\ | 
 | // RUN:   -analyzer-checker=nullability.NullableReturnedFromNonnull\ | 
 | // RUN:   -analyzer-checker=nullability.NullableDereferenced\ | 
 | // RUN:   -DNOSYSTEMHEADERS=1 -fobjc-arc\ | 
 | // RUN:   -analyzer-config nullability:NoDiagnoseCallsToSystemHeaders=true | 
 |  | 
 | #include "Inputs/system-header-simulator-for-nullability.h" | 
 |  | 
 | extern void __assert_fail(__const char *__assertion, __const char *__file, | 
 |                           unsigned int __line, __const char *__function) | 
 |     __attribute__((__noreturn__)); | 
 |  | 
 | #define assert(expr) \ | 
 |   ((expr) ? (void)(0) : __assert_fail(#expr, __FILE__, __LINE__, __func__)) | 
 |  | 
 | @interface TestObject : NSObject | 
 | - (int *_Nonnull)returnsNonnull; | 
 | - (int *_Nullable)returnsNullable; | 
 | - (int *)returnsUnspecified; | 
 | - (void)takesNonnull:(int *_Nonnull)p; | 
 | - (void)takesNonnullBlock:(void (^ _Nonnull)(void))block; | 
 | - (void)takesNullable:(int *_Nullable)p; | 
 | - (void)takesUnspecified:(int *)p; | 
 | @property(readonly, strong) NSString *stuff; | 
 | @property(readonly, nonnull) int *propReturnsNonnull; | 
 | @property(readonly, nonnull) void (^propReturnsNonnullBlock)(void); | 
 | @property(readonly, nullable) void (^propReturnsNullableBlock)(void); | 
 | @property(readonly, nullable) int *propReturnsNullable; | 
 | @property(readonly) int *propReturnsUnspecified; | 
 | + (nullable TestObject *)getNullableObject; | 
 | @end | 
 |  | 
 | TestObject * getUnspecifiedTestObject(); | 
 | TestObject *_Nonnull getNonnullTestObject(); | 
 | TestObject *_Nullable getNullableTestObject(); | 
 |  | 
 | int getRandom(); | 
 |  | 
 | typedef struct Dummy { int val; } Dummy; | 
 |  | 
 | void takesNullable(Dummy *_Nullable); | 
 | void takesNonnull(Dummy *_Nonnull); | 
 | void takesUnspecified(Dummy *); | 
 | void takesNonnullBlock(void (^ _Nonnull)(void)); | 
 | void takesNonnullObject(NSObject *_Nonnull); | 
 |  | 
 | Dummy *_Nullable returnsNullable(); | 
 | Dummy *_Nonnull returnsNonnull(); | 
 | Dummy *returnsUnspecified(); | 
 | int *_Nullable returnsNullableInt(); | 
 |  | 
 | template <typename T> T *eraseNullab(T *p) { return p; } | 
 |  | 
 | void takesAttrNonnull(Dummy *p) __attribute((nonnull(1))); | 
 |  | 
 | void testBasicRules() { | 
 |   Dummy *p = returnsNullable(); | 
 |   int *ptr = returnsNullableInt(); | 
 |   // Make every dereference a different path to avoid sinks after errors. | 
 |   switch (getRandom()) { | 
 |   case 0: { | 
 |     Dummy &r = *p; // expected-warning {{Nullable pointer is dereferenced}} | 
 |   } break; | 
 |   case 1: { | 
 |     int b = p->val; // expected-warning {{Nullable pointer is dereferenced}} | 
 |   } break; | 
 |   case 2: { | 
 |     int stuff = *ptr; // expected-warning {{Nullable pointer is dereferenced}} | 
 |   } break; | 
 |   case 3: | 
 |     takesNonnull(p); // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}} | 
 |     break; | 
 |   case 4: { | 
 |     Dummy d; | 
 |     takesNullable(&d); | 
 |     Dummy dd(d); | 
 |     break; | 
 |   } | 
 |   case 5: takesAttrNonnull(p); break; // expected-warning {{Nullable pointer is passed to}} | 
 |   default: { Dummy d = *p; } break; // expected-warning {{Nullable pointer is dereferenced}} | 
 |   } | 
 |   if (p) { | 
 |     takesNonnull(p); | 
 |     if (getRandom()) { | 
 |       Dummy &r = *p; | 
 |     } else { | 
 |       int b = p->val; | 
 |     } | 
 |   } | 
 |   Dummy *q = 0; | 
 |   if (getRandom()) { | 
 |     takesNullable(q); | 
 |     takesNonnull(q); // expected-warning {{Null passed to a callee that requires a non-null 1st parameter}} | 
 |   } | 
 |   Dummy a; | 
 |   Dummy *_Nonnull nonnull = &a; | 
 |   nonnull = q; // expected-warning {{Null assigned to a pointer which is expected to have non-null value}} | 
 |   q = &a; | 
 |   takesNullable(q); | 
 |   takesNonnull(q); | 
 | } | 
 |  | 
 | void testMultiParamChecking(Dummy *_Nonnull a, Dummy *_Nullable b, | 
 |                             Dummy *_Nonnull c); | 
 |  | 
 | void testArgumentTracking(Dummy *_Nonnull nonnull, Dummy *_Nullable nullable) { | 
 |   Dummy *p = nullable; | 
 |   Dummy *q = nonnull; | 
 |   switch(getRandom()) { | 
 |   case 1: nonnull = p; break; // expected-warning {{Nullable pointer is assigned to a pointer which is expected to have non-null value}} | 
 |   case 2: p = 0; break; | 
 |   case 3: q = p; break; | 
 |   case 4: testMultiParamChecking(nonnull, nullable, nonnull); break; | 
 |   case 5: testMultiParamChecking(nonnull, nonnull, nonnull); break; | 
 |   case 6: testMultiParamChecking(nonnull, nullable, nullable); break; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 3rd parameter}} | 
 |   case 7: testMultiParamChecking(nullable, nullable, nonnull); // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}} | 
 |   case 8: testMultiParamChecking(nullable, nullable, nullable); // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}} | 
 |   case 9: testMultiParamChecking((Dummy *_Nonnull)0, nullable, nonnull); break; | 
 |   } | 
 | } | 
 |  | 
 | void testArgumentTrackingDirectly(Dummy *_Nonnull nonnull, Dummy *_Nullable nullable) { | 
 |   switch(getRandom()) { | 
 |   case 1: testMultiParamChecking(nonnull, nullable, nonnull); break; | 
 |   case 2: testMultiParamChecking(nonnull, nonnull, nonnull); break; | 
 |   case 3: testMultiParamChecking(nonnull, nullable, nullable); break; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 3rd parameter}} | 
 |   case 4: testMultiParamChecking(nullable, nullable, nonnull); // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}} | 
 |   case 5: testMultiParamChecking(nullable, nullable, nullable); // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}} | 
 |   case 6: testMultiParamChecking((Dummy *_Nonnull)0, nullable, nonnull); break; | 
 |   } | 
 | } | 
 |  | 
 | Dummy *_Nonnull testNullableReturn(Dummy *_Nullable a) { | 
 |   Dummy *p = a; | 
 |   return p; // expected-warning {{Nullable pointer is returned from a function that is expected to return a non-null value}} | 
 | } | 
 |  | 
 | 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 testObjCMessageResultNullability() { | 
 |   // The expected result: the most nullable of self and method return type. | 
 |   TestObject *o = getUnspecifiedTestObject(); | 
 |   int *shouldBeNullable = [eraseNullab(getNullableTestObject()) returnsNonnull]; | 
 |   switch (getRandom()) { | 
 |   case 0: | 
 |     // The core analyzer assumes that the receiver is non-null after a message | 
 |     // send. This is to avoid some false positives, and increase performance | 
 |     // but it also reduces the coverage and makes this checker unable to reason | 
 |     // about the nullness of the receiver.  | 
 |     [o takesNonnull:shouldBeNullable]; // No warning expected. | 
 |     break; | 
 |   case 1: | 
 |     shouldBeNullable = | 
 |         [eraseNullab(getNullableTestObject()) returnsUnspecified]; | 
 |     [o takesNonnull:shouldBeNullable]; // No warning expected. | 
 |     break; | 
 |   case 3: | 
 |     shouldBeNullable = [eraseNullab(getNullableTestObject()) returnsNullable]; | 
 |     [o takesNonnull:shouldBeNullable]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}} | 
 |     break; | 
 |   case 4: | 
 |     shouldBeNullable = [eraseNullab(getNonnullTestObject()) returnsNullable]; | 
 |     [o takesNonnull:shouldBeNullable]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}} | 
 |     break; | 
 |   case 5: | 
 |     shouldBeNullable = | 
 |         [eraseNullab(getUnspecifiedTestObject()) returnsNullable]; | 
 |     [o takesNonnull:shouldBeNullable]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}} | 
 |     break; | 
 |   case 6: | 
 |     shouldBeNullable = [eraseNullab(getNullableTestObject()) returnsNullable]; | 
 |     [o takesNonnull:shouldBeNullable]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}} | 
 |     break; | 
 |   case 7: { | 
 |     int *shouldBeNonnull = [eraseNullab(getNonnullTestObject()) returnsNonnull]; | 
 |     [o takesNonnull:shouldBeNonnull]; | 
 |   } break; | 
 |   } | 
 | } | 
 |  | 
 | void testObjCPropertyReadNullability() { | 
 |   TestObject *o = getNonnullTestObject(); | 
 |   switch (getRandom()) { | 
 |   case 0: | 
 |     [o takesNonnull:o.propReturnsNonnull]; // no-warning | 
 |     [o takesNonnullBlock:o.propReturnsNonnullBlock]; // no-warning | 
 |     break; | 
 |   case 1: | 
 |     [o takesNonnull:o.propReturnsUnspecified]; // no-warning | 
 |     break; | 
 |   case 2: | 
 |     [o takesNonnull:o.propReturnsNullable]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}} | 
 |     break; | 
 |   case 3: | 
 |     // If a property is constrained nonnull, assume it remains nonnull | 
 |     if (o.propReturnsNullable) { | 
 |       [o takesNonnull:o.propReturnsNullable]; // no-warning | 
 |       [o takesNonnull:o.propReturnsNullable]; // no-warning | 
 |     } | 
 |     break; | 
 |   case 4: | 
 |     if (!o.propReturnsNullable) { | 
 |       [o takesNonnull:o.propReturnsNullable]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}} | 
 |     } | 
 |     break; | 
 |   case 5: | 
 |     if (!o.propReturnsNullable) { | 
 |       if (o.propReturnsNullable) { | 
 |         // Nonnull constraint from the more recent call wins | 
 |         [o takesNonnull:o.propReturnsNullable]; // no-warning | 
 |       } | 
 |     } | 
 |     break; | 
 |   case 6: | 
 |     // Constraints on property return values are receiver-qualified | 
 |     if (o.propReturnsNullable) { | 
 |       [o takesNonnull:o.propReturnsNullable];                      // no-warning | 
 |       [o takesNonnull:getNonnullTestObject().propReturnsNullable]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}} | 
 |     } | 
 |     break; | 
 |   case 7: | 
 |     // Assertions must be effective at suppressing warnings | 
 |     assert(o.propReturnsNullable); | 
 |     [o takesNonnull:o.propReturnsNullable]; // no-warning | 
 |     break; | 
 |   case 8: | 
 |     [o takesNonnullBlock:o.propReturnsNullableBlock]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}} | 
 |     break; | 
 |   case 9: | 
 |     [o takesNonnull:getNullableTestObject().propReturnsNonnull]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}} | 
 |     break; | 
 |   case 10: | 
 |     [o takesNonnull:[TestObject getNullableObject].propReturnsNonnull]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}} | 
 |     break; | 
 |   } | 
 | } | 
 |  | 
 | Dummy * _Nonnull testDirectCastNullableToNonnull() { | 
 |   Dummy *p = returnsNullable(); | 
 |   takesNonnull((Dummy * _Nonnull)p);  // no-warning | 
 |   return (Dummy * _Nonnull)p;         // no-warning | 
 | } | 
 |  | 
 | Dummy * _Nonnull testIndirectCastNullableToNonnull() { | 
 |   Dummy *p = (Dummy * _Nonnull)returnsNullable(); | 
 |   takesNonnull(p);  // no-warning | 
 |   return p;         // no-warning | 
 | } | 
 |  | 
 | Dummy * _Nonnull testDirectCastNilToNonnull() { | 
 |   takesNonnull((Dummy * _Nonnull)0);  // no-warning | 
 |   return (Dummy * _Nonnull)0;         // no-warning | 
 | } | 
 |  | 
 | void testImplicitCastNilToNonnull() { | 
 |   id obj = nil; | 
 |   takesNonnullObject(obj); // expected-warning {{nil passed to a callee that requires a non-null 1st parameter}} | 
 | } | 
 |  | 
 | void testImplicitCastNullableArgToNonnull(TestObject *_Nullable obj) { | 
 |   if (!obj) { | 
 |     takesNonnullObject(obj); // expected-warning {{nil passed to a callee that requires a non-null 1st parameter}} | 
 |   } | 
 | } | 
 |  | 
 | void testIndirectCastNilToNonnullAndPass() { | 
 |   Dummy *p = (Dummy * _Nonnull)0; | 
 |   // FIXME: Ideally the cast above would suppress this warning. | 
 |   takesNonnull(p);  // expected-warning {{Null passed to a callee that requires a non-null 1st parameter}} | 
 | } | 
 |  | 
 | void testDirectCastNilToNonnullAndAssignToLocalInInitializer() { | 
 |   Dummy * _Nonnull nonnullLocalWithAssignmentInInitializer = (Dummy * _Nonnull)0; // no-warning | 
 |   (void)nonnullLocalWithAssignmentInInitializer; | 
 |  | 
 |   // Since we've already had an invariant violation along this path, | 
 |   // we shouldn't warn here. | 
 |   nonnullLocalWithAssignmentInInitializer = 0; | 
 |   (void)nonnullLocalWithAssignmentInInitializer; | 
 |  | 
 | } | 
 |  | 
 | void testDirectCastNilToNonnullAndAssignToLocal(Dummy * _Nonnull p) { | 
 |   Dummy * _Nonnull nonnullLocalWithAssignment = p; | 
 |   nonnullLocalWithAssignment = (Dummy * _Nonnull)0; // no-warning | 
 |   (void)nonnullLocalWithAssignment; | 
 |  | 
 |   // Since we've already had an invariant violation along this path, | 
 |   // we shouldn't warn here. | 
 |   nonnullLocalWithAssignment = 0; | 
 |   (void)nonnullLocalWithAssignment; | 
 | } | 
 |  | 
 | void testDirectCastNilToNonnullAndAssignToParam(Dummy * _Nonnull p) { | 
 |   p = (Dummy * _Nonnull)0; // no-warning | 
 | } | 
 |  | 
 | @interface ClassWithNonnullIvar : NSObject { | 
 |   Dummy *_nonnullIvar; | 
 | } | 
 | @end | 
 |  | 
 | @implementation ClassWithNonnullIvar | 
 | -(void)testDirectCastNilToNonnullAndAssignToIvar { | 
 |   _nonnullIvar = (Dummy * _Nonnull)0; // no-warning; | 
 |  | 
 |   // Since we've already had an invariant violation along this path, | 
 |   // we shouldn't warn here. | 
 |   _nonnullIvar = 0; | 
 | } | 
 | @end | 
 |  | 
 | void testIndirectNilPassToNonnull() { | 
 |   Dummy *p = 0; | 
 |   takesNonnull(p);  // expected-warning {{Null passed to a callee that requires a non-null 1st parameter}} | 
 | } | 
 |  | 
 | void testBlockIndirectNilPassToNonnull() { | 
 |   void (^p)(void) = nil; | 
 |   takesNonnullBlock(p);  // expected-warning {{Null passed to a callee that requires a non-null 1st parameter}} | 
 | } | 
 |  | 
 | void testConditionalNilPassToNonnull(Dummy *p) { | 
 |   if (!p) { | 
 |     takesNonnull(p);  // expected-warning {{Null passed to a callee that requires a non-null 1st parameter}} | 
 |   } | 
 | } | 
 |  | 
 | Dummy * _Nonnull testIndirectCastNilToNonnullAndReturn() { | 
 |   Dummy *p = (Dummy * _Nonnull)0; | 
 |   // FIXME: Ideally the cast above would suppress this warning. | 
 |   return p; // expected-warning {{Null returned from a function that is expected to return a non-null value}} | 
 | } | 
 |  | 
 | void testInvalidPropagation() { | 
 |   Dummy *p = returnsUnspecified(); | 
 |   takesNullable(p); | 
 |   takesNonnull(p); | 
 | } | 
 |  | 
 | void onlyReportFirstPreconditionViolationOnPath() { | 
 |   Dummy *p = returnsNullable(); | 
 |   takesNonnull(p); // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}} | 
 |   takesNonnull(p); // No warning. | 
 |   // The first warning was not a sink. The analysis expected to continue. | 
 |   int i = 0; | 
 |   i = 5 / i; // expected-warning {{Division by zero}} | 
 |   (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); | 
 | } | 
 |  | 
 | @interface TestInlinedPreconditionViolationClass : NSObject | 
 | @end | 
 |  | 
 | @implementation TestInlinedPreconditionViolationClass | 
 | -(Dummy * _Nonnull) calleeWithParam:(Dummy * _Nonnull) p2 { | 
 |   Dummy *x = 0; | 
 |   if (!p2) // p2 binding becomes dead at this point. | 
 |     return x; // no-warning | 
 |   else | 
 |    return p2; | 
 | } | 
 |  | 
 | -(Dummy *)callerWithParam:(Dummy * _Nonnull) p1 { | 
 |   return [self calleeWithParam:p1]; | 
 | } | 
 |  | 
 | @end | 
 |  | 
 | int * _Nonnull InlinedPreconditionViolationInFunctionCallee(int * _Nonnull p2) { | 
 |   int *x = 0; | 
 |   if (!p2) // p2 binding becomes dead at this point. | 
 |     return x; // no-warning | 
 |   else | 
 |    return p2; | 
 | } | 
 |  | 
 | int * _Nonnull InlinedReturnNullOverSuppressionCallee(int * _Nonnull p2) { | 
 |   int *result = 0; | 
 |   return result; // no-warning; but this is an over suppression | 
 | } | 
 |  | 
 | int *InlinedReturnNullOverSuppressionCaller(int * _Nonnull p1) { | 
 |   return InlinedReturnNullOverSuppressionCallee(p1); | 
 | } | 
 |  | 
 | void inlinedNullable(Dummy *_Nullable p) { | 
 |   if (p) return; | 
 | } | 
 | void inlinedNonnull(Dummy *_Nonnull p) { | 
 |   if (p) return; | 
 | } | 
 | void inlinedUnspecified(Dummy *p) { | 
 |   if (p) return; | 
 | } | 
 |  | 
 | void testNilReturnWithBlock(Dummy *p) { | 
 |   p = 0; | 
 |   Dummy *_Nonnull (^myblock)(void) = ^Dummy *_Nonnull(void) { | 
 |     return p; // TODO: We should warn in blocks. | 
 |   }; | 
 |   myblock(); | 
 | } | 
 |  | 
 | 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);  // no-warning | 
 |  | 
 |   if (getRandom()) { | 
 |     Dummy *_Nonnull varWithInitializer = p; // no-warning | 
 |  | 
 |      Dummy *_Nonnull var1WithInitializer = p,  // no-warning | 
 |            *_Nonnull var2WithInitializer = p;  // no-warning | 
 |   } | 
 |  | 
 |   if (getRandom()) { | 
 |     Dummy *_Nonnull varWithoutInitializer; | 
 |     varWithoutInitializer = p; // no-warning | 
 |   } | 
 |  | 
 |   return p; | 
 | } | 
 |  | 
 |  | 
 | @interface SomeClass : NSObject { | 
 |   int instanceVar; | 
 | } | 
 | @end | 
 |  | 
 | @implementation SomeClass (MethodReturn) | 
 | - (id)initWithSomething:(int)i { | 
 |   if (self = [super init]) { | 
 |     instanceVar = i; | 
 |   } | 
 |  | 
 |   return self; | 
 | } | 
 |  | 
 | - (TestObject * _Nonnull)testReturnsNullableInNonnullIndirectly { | 
 |   TestObject *local = getNullableTestObject(); | 
 |   return local; // expected-warning {{Nullable pointer is returned from a method that is expected to return a non-null value}} | 
 | } | 
 |  | 
 | - (TestObject * _Nonnull)testReturnsCastSuppressedNullableInNonnullIndirectly { | 
 |   TestObject *local = getNullableTestObject(); | 
 |   return (TestObject * _Nonnull)local; // no-warning | 
 | } | 
 |  | 
 | - (TestObject * _Nonnull)testReturnsNullableInNonnullWhenPreconditionViolated:(TestObject * _Nonnull) p { | 
 |   TestObject *local = getNullableTestObject(); | 
 |   if (!p) // Pre-condition violated here. | 
 |     return local; // no-warning | 
 |   else | 
 |     return p; // no-warning | 
 | } | 
 | @end | 
 |  | 
 | @interface ClassWithInitializers : NSObject | 
 | @end | 
 |  | 
 | @implementation ClassWithInitializers | 
 | - (instancetype _Nonnull)initWithNonnullReturnAndSelfCheckingIdiom { | 
 |   // This defensive check is a common-enough idiom that we filter 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; | 
 | } | 
 | @end | 
 |  | 
 | @interface SubClassWithInitializers : ClassWithInitializers | 
 | @end | 
 |  | 
 | @implementation SubClassWithInitializers | 
 | // Note: Because this is overriding | 
 | // -[ClassWithInitializers initWithNonnullReturnAndSelfCheckingIdiom], | 
 | // the return type of this method becomes implicitly id _Nonnull. | 
 | - (id)initWithNonnullReturnAndSelfCheckingIdiom { | 
 |   if (self = [super initWithNonnullReturnAndSelfCheckingIdiom]) { | 
 |   } | 
 |  | 
 |   return self; // no-warning | 
 | } | 
 |  | 
 | - (id _Nonnull)initWithNonnullReturnAndSelfCheckingIdiomV2; { | 
 |   // Another common return-checking idiom | 
 |   self = [super initWithNonnullReturnAndSelfCheckingIdiom]; | 
 |   if (!self) { | 
 |     return nil; // no-warning | 
 |   } | 
 |  | 
 |   return self; | 
 | } | 
 | @end | 
 |  | 
 | @interface ClassWithCopyWithZone : NSObject<NSCopying,NSMutableCopying> { | 
 |   id i; | 
 | } | 
 |  | 
 | @end | 
 |  | 
 | @implementation ClassWithCopyWithZone | 
 | -(id)copyWithZone:(NSZone *)zone { | 
 |   ClassWithCopyWithZone *newInstance = [[ClassWithCopyWithZone alloc] init]; | 
 |   if (!newInstance) | 
 |     return nil; | 
 |  | 
 |   newInstance->i = i; | 
 |   return newInstance; | 
 | } | 
 |  | 
 | -(id)mutableCopyWithZone:(NSZone *)zone { | 
 |   ClassWithCopyWithZone *newInstance = [[ClassWithCopyWithZone alloc] init]; | 
 |   if (newInstance) { | 
 |     newInstance->i = i; | 
 |   } | 
 |  | 
 |   return newInstance; | 
 | } | 
 | @end | 
 |  | 
 | NSString * _Nullable returnsNullableString(); | 
 |  | 
 | void callFunctionInSystemHeader() { | 
 |   NSString *s = returnsNullableString(); | 
 |  | 
 |   NSSystemFunctionTakingNonnull(s); | 
 |   #if !NOSYSTEMHEADERS | 
 |   // expected-warning@-2{{Nullable pointer is passed to a callee that requires a non-null 1st parameter}} | 
 |   #endif | 
 | } | 
 |  | 
 | void callMethodInSystemHeader() { | 
 |   NSString *s = returnsNullableString(); | 
 |  | 
 |   NSSystemClass *sc = [[NSSystemClass alloc] init]; | 
 |   [sc takesNonnull:s]; | 
 |   #if !NOSYSTEMHEADERS | 
 |   // expected-warning@-2{{Nullable pointer is passed to a callee that requires a non-null 1st parameter}} | 
 |   #endif | 
 | } | 
 |  | 
 | // Test to make sure the analyzer doesn't warn when an a nullability invariant | 
 | // has already been found to be violated on an instance variable. | 
 |  | 
 | @class MyInternalClass; | 
 | @interface MyClass : NSObject { | 
 |   MyInternalClass * _Nonnull _internal; | 
 | } | 
 | @end | 
 |  | 
 | @interface MyInternalClass : NSObject { | 
 |   @public | 
 |   id _someIvar; | 
 | } | 
 | -(id _Nonnull)methodWithInternalImplementation; | 
 | @end | 
 |  | 
 | @interface MyClass () { | 
 |   MyInternalClass * _Nonnull _nilledOutInternal; | 
 | } | 
 | @end | 
 |  | 
 | @implementation MyClass | 
 | -(id _Nonnull)methodWithInternalImplementation { | 
 |   if (!_internal) | 
 |     return nil; // no-warning | 
 |  | 
 |   return [_internal methodWithInternalImplementation]; | 
 | } | 
 |  | 
 | - (id _Nonnull)methodReturningIvarInImplementation; { | 
 |   return _internal == 0 ? nil : _internal->_someIvar; // no-warning | 
 | } | 
 |  | 
 | -(id _Nonnull)methodWithNilledOutInternal { | 
 |   _nilledOutInternal = (id _Nonnull)nil; | 
 |  | 
 |   return nil; // no-warning | 
 | } | 
 | @end |