1*67e74705SXin Li// RUN: %clang_cc1 -analyze -fobjc-arc -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull -DNOSYSTEMHEADERS=0 -verify %s 2*67e74705SXin Li// RUN: %clang_cc1 -analyze -fobjc-arc -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull -analyzer-config nullability:NoDiagnoseCallsToSystemHeaders=true -DNOSYSTEMHEADERS=1 -verify %s 3*67e74705SXin Li 4*67e74705SXin Li#include "Inputs/system-header-simulator-for-nullability.h" 5*67e74705SXin Li 6*67e74705SXin Liint getRandom(); 7*67e74705SXin Li 8*67e74705SXin Litypedef struct Dummy { int val; } Dummy; 9*67e74705SXin Li 10*67e74705SXin Livoid takesNullable(Dummy *_Nullable); 11*67e74705SXin Livoid takesNonnull(Dummy *_Nonnull); 12*67e74705SXin LiDummy *_Nullable returnsNullable(); 13*67e74705SXin Li 14*67e74705SXin Livoid testBasicRules() { 15*67e74705SXin Li // The tracking of nullable values is turned off. 16*67e74705SXin Li Dummy *p = returnsNullable(); 17*67e74705SXin Li takesNonnull(p); // no warning 18*67e74705SXin Li Dummy *q = 0; 19*67e74705SXin Li if (getRandom()) { 20*67e74705SXin Li takesNullable(q); 21*67e74705SXin Li takesNonnull(q); // expected-warning {{Null passed to a callee that requires a non-null 1st parameter}} 22*67e74705SXin Li } 23*67e74705SXin Li} 24*67e74705SXin Li 25*67e74705SXin LiDummy *_Nonnull testNullReturn() { 26*67e74705SXin Li Dummy *p = 0; 27*67e74705SXin Li return p; // expected-warning {{Null is returned from a function that is expected to return a non-null value}} 28*67e74705SXin Li} 29*67e74705SXin Li 30*67e74705SXin Livoid onlyReportFirstPreconditionViolationOnPath() { 31*67e74705SXin Li Dummy *p = 0; 32*67e74705SXin Li takesNonnull(p); // expected-warning {{Null passed to a callee that requires a non-null 1st parameter}} 33*67e74705SXin Li takesNonnull(p); // No warning. 34*67e74705SXin Li // Passing null to nonnull is a sink. Stop the analysis. 35*67e74705SXin Li int i = 0; 36*67e74705SXin Li i = 5 / i; // no warning 37*67e74705SXin Li (void)i; 38*67e74705SXin Li} 39*67e74705SXin Li 40*67e74705SXin LiDummy *_Nonnull doNotWarnWhenPreconditionIsViolatedInTopFunc( 41*67e74705SXin Li Dummy *_Nonnull p) { 42*67e74705SXin Li if (!p) { 43*67e74705SXin Li Dummy *ret = 44*67e74705SXin Li 0; // avoid compiler warning (which is not generated by the analyzer) 45*67e74705SXin Li if (getRandom()) 46*67e74705SXin Li return ret; // no warning 47*67e74705SXin Li else 48*67e74705SXin Li return p; // no warning 49*67e74705SXin Li } else { 50*67e74705SXin Li return p; 51*67e74705SXin Li } 52*67e74705SXin Li} 53*67e74705SXin Li 54*67e74705SXin LiDummy *_Nonnull doNotWarnWhenPreconditionIsViolated(Dummy *_Nonnull p) { 55*67e74705SXin Li if (!p) { 56*67e74705SXin Li Dummy *ret = 57*67e74705SXin Li 0; // avoid compiler warning (which is not generated by the analyzer) 58*67e74705SXin Li if (getRandom()) 59*67e74705SXin Li return ret; // no warning 60*67e74705SXin Li else 61*67e74705SXin Li return p; // no warning 62*67e74705SXin Li } else { 63*67e74705SXin Li return p; 64*67e74705SXin Li } 65*67e74705SXin Li} 66*67e74705SXin Li 67*67e74705SXin Livoid testPreconditionViolationInInlinedFunction(Dummy *p) { 68*67e74705SXin Li doNotWarnWhenPreconditionIsViolated(p); 69*67e74705SXin Li} 70*67e74705SXin Li 71*67e74705SXin Livoid inlinedNullable(Dummy *_Nullable p) { 72*67e74705SXin Li if (p) return; 73*67e74705SXin Li} 74*67e74705SXin Livoid inlinedNonnull(Dummy *_Nonnull p) { 75*67e74705SXin Li if (p) return; 76*67e74705SXin Li} 77*67e74705SXin Livoid inlinedUnspecified(Dummy *p) { 78*67e74705SXin Li if (p) return; 79*67e74705SXin Li} 80*67e74705SXin Li 81*67e74705SXin LiDummy *_Nonnull testDefensiveInlineChecks(Dummy * p) { 82*67e74705SXin Li switch (getRandom()) { 83*67e74705SXin Li case 1: inlinedNullable(p); break; 84*67e74705SXin Li case 2: inlinedNonnull(p); break; 85*67e74705SXin Li case 3: inlinedUnspecified(p); break; 86*67e74705SXin Li } 87*67e74705SXin Li if (getRandom()) 88*67e74705SXin Li takesNonnull(p); 89*67e74705SXin Li return p; 90*67e74705SXin Li} 91*67e74705SXin Li 92*67e74705SXin Li@interface TestObject : NSObject 93*67e74705SXin Li@end 94*67e74705SXin Li 95*67e74705SXin LiTestObject *_Nonnull getNonnullTestObject(); 96*67e74705SXin Li 97*67e74705SXin Livoid testObjCARCImplicitZeroInitialization() { 98*67e74705SXin Li TestObject * _Nonnull implicitlyZeroInitialized; // no-warning 99*67e74705SXin Li implicitlyZeroInitialized = getNonnullTestObject(); 100*67e74705SXin Li} 101*67e74705SXin Li 102*67e74705SXin Livoid testObjCARCExplicitZeroInitialization() { 103*67e74705SXin Li TestObject * _Nonnull explicitlyZeroInitialized = nil; // expected-warning {{Null is assigned to a pointer which is expected to have non-null value}} 104*67e74705SXin Li} 105*67e74705SXin Li 106*67e74705SXin Li// Under ARC, returned expressions of ObjC objects types are are implicitly 107*67e74705SXin Li// cast to _Nonnull when the functions return type is _Nonnull, so make 108*67e74705SXin Li// sure this doesn't implicit cast doesn't suppress a legitimate warning. 109*67e74705SXin LiTestObject * _Nonnull returnsNilObjCInstanceIndirectly() { 110*67e74705SXin Li TestObject *local = 0; 111*67e74705SXin Li return local; // expected-warning {{Null is returned from a function that is expected to return a non-null value}} 112*67e74705SXin Li} 113*67e74705SXin Li 114*67e74705SXin LiTestObject * _Nonnull returnsNilObjCInstanceIndirectlyWithSupressingCast() { 115*67e74705SXin Li TestObject *local = 0; 116*67e74705SXin Li return (TestObject * _Nonnull)local; // no-warning 117*67e74705SXin Li} 118*67e74705SXin Li 119*67e74705SXin LiTestObject * _Nonnull returnsNilObjCInstanceDirectly() { 120*67e74705SXin Li return nil; // expected-warning {{Null is returned from a function that is expected to return a non-null value}} 121*67e74705SXin Li} 122*67e74705SXin Li 123*67e74705SXin LiTestObject * _Nonnull returnsNilObjCInstanceDirectlyWithSuppressingCast() { 124*67e74705SXin Li return (TestObject * _Nonnull)nil; // no-warning 125*67e74705SXin Li} 126*67e74705SXin Li 127*67e74705SXin Li@interface SomeClass : NSObject 128*67e74705SXin Li@end 129*67e74705SXin Li 130*67e74705SXin Li@implementation SomeClass (MethodReturn) 131*67e74705SXin Li- (SomeClass * _Nonnull)testReturnsNilInNonnull { 132*67e74705SXin Li SomeClass *local = nil; 133*67e74705SXin Li return local; // expected-warning {{Null is returned from a method that is expected to return a non-null value}} 134*67e74705SXin Li} 135*67e74705SXin Li 136*67e74705SXin Li- (SomeClass * _Nonnull)testReturnsCastSuppressedNilInNonnull { 137*67e74705SXin Li SomeClass *local = nil; 138*67e74705SXin Li return (SomeClass * _Nonnull)local; // no-warning 139*67e74705SXin Li} 140*67e74705SXin Li 141*67e74705SXin Li- (SomeClass * _Nonnull)testReturnsNilInNonnullWhenPreconditionViolated:(SomeClass * _Nonnull) p { 142*67e74705SXin Li SomeClass *local = nil; 143*67e74705SXin Li if (!p) // Pre-condition violated here. 144*67e74705SXin Li return local; // no-warning 145*67e74705SXin Li else 146*67e74705SXin Li return p; // no-warning 147*67e74705SXin Li} 148*67e74705SXin Li@end 149*67e74705SXin Li 150*67e74705SXin Li 151*67e74705SXin Livoid callFunctionInSystemHeader() { 152*67e74705SXin Li NSString *s; 153*67e74705SXin Li s = nil; 154*67e74705SXin Li 155*67e74705SXin Li NSSystemFunctionTakingNonnull(s); 156*67e74705SXin Li #if !NOSYSTEMHEADERS 157*67e74705SXin Li // expected-warning@-2{{Null passed to a callee that requires a non-null 1st parameter}} 158*67e74705SXin Li #endif 159*67e74705SXin Li} 160*67e74705SXin Li 161*67e74705SXin Livoid callMethodInSystemHeader() { 162*67e74705SXin Li NSString *s; 163*67e74705SXin Li s = nil; 164*67e74705SXin Li 165*67e74705SXin Li NSSystemClass *sc = [[NSSystemClass alloc] init]; 166*67e74705SXin Li [sc takesNonnull:s]; 167*67e74705SXin Li #if !NOSYSTEMHEADERS 168*67e74705SXin Li // expected-warning@-2{{Null passed to a callee that requires a non-null 1st parameter}} 169*67e74705SXin Li #endif 170*67e74705SXin Li} 171