1*67e74705SXin Li// RUN: %clang_cc1 -fblocks -analyze -analyzer-checker=core,nullability -DNOSYSTEMHEADERS=0 -verify %s 2*67e74705SXin Li// RUN: %clang_cc1 -fblocks -analyze -analyzer-checker=core,nullability -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 Li@interface TestObject : NSObject 7*67e74705SXin Li- (int *_Nonnull)returnsNonnull; 8*67e74705SXin Li- (int *_Nullable)returnsNullable; 9*67e74705SXin Li- (int *)returnsUnspecified; 10*67e74705SXin Li- (void)takesNonnull:(int *_Nonnull)p; 11*67e74705SXin Li- (void)takesNullable:(int *_Nullable)p; 12*67e74705SXin Li- (void)takesUnspecified:(int *)p; 13*67e74705SXin Li@property(readonly, strong) NSString *stuff; 14*67e74705SXin Li@end 15*67e74705SXin Li 16*67e74705SXin LiTestObject * getUnspecifiedTestObject(); 17*67e74705SXin LiTestObject *_Nonnull getNonnullTestObject(); 18*67e74705SXin LiTestObject *_Nullable getNullableTestObject(); 19*67e74705SXin Li 20*67e74705SXin Liint getRandom(); 21*67e74705SXin Li 22*67e74705SXin Litypedef struct Dummy { int val; } Dummy; 23*67e74705SXin Li 24*67e74705SXin Livoid takesNullable(Dummy *_Nullable); 25*67e74705SXin Livoid takesNonnull(Dummy *_Nonnull); 26*67e74705SXin Livoid takesUnspecified(Dummy *); 27*67e74705SXin Li 28*67e74705SXin LiDummy *_Nullable returnsNullable(); 29*67e74705SXin LiDummy *_Nonnull returnsNonnull(); 30*67e74705SXin LiDummy *returnsUnspecified(); 31*67e74705SXin Liint *_Nullable returnsNullableInt(); 32*67e74705SXin Li 33*67e74705SXin Litemplate <typename T> T *eraseNullab(T *p) { return p; } 34*67e74705SXin Li 35*67e74705SXin Livoid takesAttrNonnull(Dummy *p) __attribute((nonnull(1))); 36*67e74705SXin Li 37*67e74705SXin Livoid testBasicRules() { 38*67e74705SXin Li Dummy *p = returnsNullable(); 39*67e74705SXin Li int *ptr = returnsNullableInt(); 40*67e74705SXin Li // Make every dereference a different path to avoid sinks after errors. 41*67e74705SXin Li switch (getRandom()) { 42*67e74705SXin Li case 0: { 43*67e74705SXin Li Dummy &r = *p; // expected-warning {{Nullable pointer is dereferenced}} 44*67e74705SXin Li } break; 45*67e74705SXin Li case 1: { 46*67e74705SXin Li int b = p->val; // expected-warning {{Nullable pointer is dereferenced}} 47*67e74705SXin Li } break; 48*67e74705SXin Li case 2: { 49*67e74705SXin Li int stuff = *ptr; // expected-warning {{Nullable pointer is dereferenced}} 50*67e74705SXin Li } break; 51*67e74705SXin Li case 3: 52*67e74705SXin Li takesNonnull(p); // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}} 53*67e74705SXin Li break; 54*67e74705SXin Li case 4: { 55*67e74705SXin Li Dummy d; 56*67e74705SXin Li takesNullable(&d); 57*67e74705SXin Li Dummy dd(d); 58*67e74705SXin Li break; 59*67e74705SXin Li } 60*67e74705SXin Li case 5: takesAttrNonnull(p); break; // expected-warning {{Nullable pointer is passed to}} 61*67e74705SXin Li default: { Dummy d = *p; } break; // expected-warning {{Nullable pointer is dereferenced}} 62*67e74705SXin Li } 63*67e74705SXin Li if (p) { 64*67e74705SXin Li takesNonnull(p); 65*67e74705SXin Li if (getRandom()) { 66*67e74705SXin Li Dummy &r = *p; 67*67e74705SXin Li } else { 68*67e74705SXin Li int b = p->val; 69*67e74705SXin Li } 70*67e74705SXin Li } 71*67e74705SXin Li Dummy *q = 0; 72*67e74705SXin Li if (getRandom()) { 73*67e74705SXin Li takesNullable(q); 74*67e74705SXin Li takesNonnull(q); // expected-warning {{Null passed to a callee that requires a non-null 1st parameter}} 75*67e74705SXin Li } 76*67e74705SXin Li Dummy a; 77*67e74705SXin Li Dummy *_Nonnull nonnull = &a; 78*67e74705SXin Li nonnull = q; // expected-warning {{Null is assigned to a pointer which is expected to have non-null value}} 79*67e74705SXin Li q = &a; 80*67e74705SXin Li takesNullable(q); 81*67e74705SXin Li takesNonnull(q); 82*67e74705SXin Li} 83*67e74705SXin Li 84*67e74705SXin Livoid testMultiParamChecking(Dummy *_Nonnull a, Dummy *_Nullable b, 85*67e74705SXin Li Dummy *_Nonnull c); 86*67e74705SXin Li 87*67e74705SXin Livoid testArgumentTracking(Dummy *_Nonnull nonnull, Dummy *_Nullable nullable) { 88*67e74705SXin Li Dummy *p = nullable; 89*67e74705SXin Li Dummy *q = nonnull; 90*67e74705SXin Li switch(getRandom()) { 91*67e74705SXin Li case 1: nonnull = p; break; // expected-warning {{Nullable pointer is assigned to a pointer which is expected to have non-null value}} 92*67e74705SXin Li case 2: p = 0; break; 93*67e74705SXin Li case 3: q = p; break; 94*67e74705SXin Li case 4: testMultiParamChecking(nonnull, nullable, nonnull); break; 95*67e74705SXin Li case 5: testMultiParamChecking(nonnull, nonnull, nonnull); break; 96*67e74705SXin Li case 6: testMultiParamChecking(nonnull, nullable, nullable); break; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 3rd parameter}} 97*67e74705SXin Li case 7: testMultiParamChecking(nullable, nullable, nonnull); // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}} 98*67e74705SXin Li case 8: testMultiParamChecking(nullable, nullable, nullable); // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}} 99*67e74705SXin Li case 9: testMultiParamChecking((Dummy *_Nonnull)0, nullable, nonnull); break; 100*67e74705SXin Li } 101*67e74705SXin Li} 102*67e74705SXin Li 103*67e74705SXin LiDummy *_Nonnull testNullableReturn(Dummy *_Nullable a) { 104*67e74705SXin Li Dummy *p = a; 105*67e74705SXin Li return p; // expected-warning {{Nullable pointer is returned from a function that is expected to return a non-null value}} 106*67e74705SXin Li} 107*67e74705SXin Li 108*67e74705SXin LiDummy *_Nonnull testNullReturn() { 109*67e74705SXin Li Dummy *p = 0; 110*67e74705SXin Li return p; // expected-warning {{Null is returned from a function that is expected to return a non-null value}} 111*67e74705SXin Li} 112*67e74705SXin Li 113*67e74705SXin Livoid testObjCMessageResultNullability() { 114*67e74705SXin Li // The expected result: the most nullable of self and method return type. 115*67e74705SXin Li TestObject *o = getUnspecifiedTestObject(); 116*67e74705SXin Li int *shouldBeNullable = [eraseNullab(getNullableTestObject()) returnsNonnull]; 117*67e74705SXin Li switch (getRandom()) { 118*67e74705SXin Li case 0: 119*67e74705SXin Li // The core analyzer assumes that the receiver is non-null after a message 120*67e74705SXin Li // send. This is to avoid some false positives, and increase performance 121*67e74705SXin Li // but it also reduces the coverage and makes this checker unable to reason 122*67e74705SXin Li // about the nullness of the receiver. 123*67e74705SXin Li [o takesNonnull:shouldBeNullable]; // No warning expected. 124*67e74705SXin Li break; 125*67e74705SXin Li case 1: 126*67e74705SXin Li shouldBeNullable = 127*67e74705SXin Li [eraseNullab(getNullableTestObject()) returnsUnspecified]; 128*67e74705SXin Li [o takesNonnull:shouldBeNullable]; // No warning expected. 129*67e74705SXin Li break; 130*67e74705SXin Li case 3: 131*67e74705SXin Li shouldBeNullable = [eraseNullab(getNullableTestObject()) returnsNullable]; 132*67e74705SXin Li [o takesNonnull:shouldBeNullable]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}} 133*67e74705SXin Li break; 134*67e74705SXin Li case 4: 135*67e74705SXin Li shouldBeNullable = [eraseNullab(getNonnullTestObject()) returnsNullable]; 136*67e74705SXin Li [o takesNonnull:shouldBeNullable]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}} 137*67e74705SXin Li break; 138*67e74705SXin Li case 5: 139*67e74705SXin Li shouldBeNullable = 140*67e74705SXin Li [eraseNullab(getUnspecifiedTestObject()) returnsNullable]; 141*67e74705SXin Li [o takesNonnull:shouldBeNullable]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}} 142*67e74705SXin Li break; 143*67e74705SXin Li case 6: 144*67e74705SXin Li shouldBeNullable = [eraseNullab(getNullableTestObject()) returnsNullable]; 145*67e74705SXin Li [o takesNonnull:shouldBeNullable]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}} 146*67e74705SXin Li break; 147*67e74705SXin Li case 7: { 148*67e74705SXin Li int *shouldBeNonnull = [eraseNullab(getNonnullTestObject()) returnsNonnull]; 149*67e74705SXin Li [o takesNonnull:shouldBeNonnull]; 150*67e74705SXin Li } break; 151*67e74705SXin Li } 152*67e74705SXin Li} 153*67e74705SXin Li 154*67e74705SXin LiDummy * _Nonnull testDirectCastNullableToNonnull() { 155*67e74705SXin Li Dummy *p = returnsNullable(); 156*67e74705SXin Li takesNonnull((Dummy * _Nonnull)p); // no-warning 157*67e74705SXin Li return (Dummy * _Nonnull)p; // no-warning 158*67e74705SXin Li} 159*67e74705SXin Li 160*67e74705SXin LiDummy * _Nonnull testIndirectCastNullableToNonnull() { 161*67e74705SXin Li Dummy *p = (Dummy * _Nonnull)returnsNullable(); 162*67e74705SXin Li takesNonnull(p); // no-warning 163*67e74705SXin Li return p; // no-warning 164*67e74705SXin Li} 165*67e74705SXin Li 166*67e74705SXin LiDummy * _Nonnull testDirectCastNilToNonnull() { 167*67e74705SXin Li takesNonnull((Dummy * _Nonnull)0); // no-warning 168*67e74705SXin Li return (Dummy * _Nonnull)0; // no-warning 169*67e74705SXin Li} 170*67e74705SXin Li 171*67e74705SXin Livoid testIndirectCastNilToNonnullAndPass() { 172*67e74705SXin Li Dummy *p = (Dummy * _Nonnull)0; 173*67e74705SXin Li // FIXME: Ideally the cast above would suppress this warning. 174*67e74705SXin Li takesNonnull(p); // expected-warning {{Null passed to a callee that requires a non-null 1st parameter}} 175*67e74705SXin Li} 176*67e74705SXin Li 177*67e74705SXin Livoid testDirectCastNilToNonnullAndAssignToLocalInInitializer() { 178*67e74705SXin Li Dummy * _Nonnull nonnullLocalWithAssignmentInInitializer = (Dummy * _Nonnull)0; // no-warning 179*67e74705SXin Li (void)nonnullLocalWithAssignmentInInitializer; 180*67e74705SXin Li 181*67e74705SXin Li // Since we've already had an invariant violation along this path, 182*67e74705SXin Li // we shouldn't warn here. 183*67e74705SXin Li nonnullLocalWithAssignmentInInitializer = 0; 184*67e74705SXin Li (void)nonnullLocalWithAssignmentInInitializer; 185*67e74705SXin Li 186*67e74705SXin Li} 187*67e74705SXin Li 188*67e74705SXin Livoid testDirectCastNilToNonnullAndAssignToLocal(Dummy * _Nonnull p) { 189*67e74705SXin Li Dummy * _Nonnull nonnullLocalWithAssignment = p; 190*67e74705SXin Li nonnullLocalWithAssignment = (Dummy * _Nonnull)0; // no-warning 191*67e74705SXin Li (void)nonnullLocalWithAssignment; 192*67e74705SXin Li 193*67e74705SXin Li // Since we've already had an invariant violation along this path, 194*67e74705SXin Li // we shouldn't warn here. 195*67e74705SXin Li nonnullLocalWithAssignment = 0; 196*67e74705SXin Li (void)nonnullLocalWithAssignment; 197*67e74705SXin Li} 198*67e74705SXin Li 199*67e74705SXin Livoid testDirectCastNilToNonnullAndAssignToParam(Dummy * _Nonnull p) { 200*67e74705SXin Li p = (Dummy * _Nonnull)0; // no-warning 201*67e74705SXin Li} 202*67e74705SXin Li 203*67e74705SXin Li@interface ClassWithNonnullIvar : NSObject { 204*67e74705SXin Li Dummy *_nonnullIvar; 205*67e74705SXin Li} 206*67e74705SXin Li@end 207*67e74705SXin Li 208*67e74705SXin Li@implementation ClassWithNonnullIvar 209*67e74705SXin Li-(void)testDirectCastNilToNonnullAndAssignToIvar { 210*67e74705SXin Li _nonnullIvar = (Dummy * _Nonnull)0; // no-warning; 211*67e74705SXin Li 212*67e74705SXin Li // Since we've already had an invariant violation along this path, 213*67e74705SXin Li // we shouldn't warn here. 214*67e74705SXin Li _nonnullIvar = 0; 215*67e74705SXin Li} 216*67e74705SXin Li@end 217*67e74705SXin Li 218*67e74705SXin Livoid testIndirectNilPassToNonnull() { 219*67e74705SXin Li Dummy *p = 0; 220*67e74705SXin Li takesNonnull(p); // expected-warning {{Null passed to a callee that requires a non-null 1st parameter}} 221*67e74705SXin Li} 222*67e74705SXin Li 223*67e74705SXin Livoid testConditionalNilPassToNonnull(Dummy *p) { 224*67e74705SXin Li if (!p) { 225*67e74705SXin Li takesNonnull(p); // expected-warning {{Null passed to a callee that requires a non-null 1st parameter}} 226*67e74705SXin Li } 227*67e74705SXin Li} 228*67e74705SXin Li 229*67e74705SXin LiDummy * _Nonnull testIndirectCastNilToNonnullAndReturn() { 230*67e74705SXin Li Dummy *p = (Dummy * _Nonnull)0; 231*67e74705SXin Li // FIXME: Ideally the cast above would suppress this warning. 232*67e74705SXin Li return p; // expected-warning {{Null is returned from a function that is expected to return a non-null value}} 233*67e74705SXin Li} 234*67e74705SXin Li 235*67e74705SXin Livoid testInvalidPropagation() { 236*67e74705SXin Li Dummy *p = returnsUnspecified(); 237*67e74705SXin Li takesNullable(p); 238*67e74705SXin Li takesNonnull(p); 239*67e74705SXin Li} 240*67e74705SXin Li 241*67e74705SXin Livoid onlyReportFirstPreconditionViolationOnPath() { 242*67e74705SXin Li Dummy *p = returnsNullable(); 243*67e74705SXin Li takesNonnull(p); // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}} 244*67e74705SXin Li takesNonnull(p); // No warning. 245*67e74705SXin Li // The first warning was not a sink. The analysis expected to continue. 246*67e74705SXin Li int i = 0; 247*67e74705SXin Li i = 5 / i; // expected-warning {{Division by zero}} 248*67e74705SXin Li (void)i; 249*67e74705SXin Li} 250*67e74705SXin Li 251*67e74705SXin LiDummy *_Nonnull doNotWarnWhenPreconditionIsViolatedInTopFunc( 252*67e74705SXin Li Dummy *_Nonnull p) { 253*67e74705SXin Li if (!p) { 254*67e74705SXin Li Dummy *ret = 255*67e74705SXin Li 0; // avoid compiler warning (which is not generated by the analyzer) 256*67e74705SXin Li if (getRandom()) 257*67e74705SXin Li return ret; // no warning 258*67e74705SXin Li else 259*67e74705SXin Li return p; // no warning 260*67e74705SXin Li } else { 261*67e74705SXin Li return p; 262*67e74705SXin Li } 263*67e74705SXin Li} 264*67e74705SXin Li 265*67e74705SXin LiDummy *_Nonnull doNotWarnWhenPreconditionIsViolated(Dummy *_Nonnull p) { 266*67e74705SXin Li if (!p) { 267*67e74705SXin Li Dummy *ret = 268*67e74705SXin Li 0; // avoid compiler warning (which is not generated by the analyzer) 269*67e74705SXin Li if (getRandom()) 270*67e74705SXin Li return ret; // no warning 271*67e74705SXin Li else 272*67e74705SXin Li return p; // no warning 273*67e74705SXin Li } else { 274*67e74705SXin Li return p; 275*67e74705SXin Li } 276*67e74705SXin Li} 277*67e74705SXin Li 278*67e74705SXin Livoid testPreconditionViolationInInlinedFunction(Dummy *p) { 279*67e74705SXin Li doNotWarnWhenPreconditionIsViolated(p); 280*67e74705SXin Li} 281*67e74705SXin Li 282*67e74705SXin Li@interface TestInlinedPreconditionViolationClass : NSObject 283*67e74705SXin Li@end 284*67e74705SXin Li 285*67e74705SXin Li@implementation TestInlinedPreconditionViolationClass 286*67e74705SXin Li-(Dummy * _Nonnull) calleeWithParam:(Dummy * _Nonnull) p2 { 287*67e74705SXin Li Dummy *x = 0; 288*67e74705SXin Li if (!p2) // p2 binding becomes dead at this point. 289*67e74705SXin Li return x; // no-warning 290*67e74705SXin Li else 291*67e74705SXin Li return p2; 292*67e74705SXin Li} 293*67e74705SXin Li 294*67e74705SXin Li-(Dummy *)callerWithParam:(Dummy * _Nonnull) p1 { 295*67e74705SXin Li return [self calleeWithParam:p1]; 296*67e74705SXin Li} 297*67e74705SXin Li 298*67e74705SXin Li@end 299*67e74705SXin Li 300*67e74705SXin Liint * _Nonnull InlinedPreconditionViolationInFunctionCallee(int * _Nonnull p2) { 301*67e74705SXin Li int *x = 0; 302*67e74705SXin Li if (!p2) // p2 binding becomes dead at this point. 303*67e74705SXin Li return x; // no-warning 304*67e74705SXin Li else 305*67e74705SXin Li return p2; 306*67e74705SXin Li} 307*67e74705SXin Li 308*67e74705SXin Liint * _Nonnull InlinedReturnNullOverSuppressionCallee(int * _Nonnull p2) { 309*67e74705SXin Li int *result = 0; 310*67e74705SXin Li return result; // no-warning; but this is an over suppression 311*67e74705SXin Li} 312*67e74705SXin Li 313*67e74705SXin Liint *InlinedReturnNullOverSuppressionCaller(int * _Nonnull p1) { 314*67e74705SXin Li return InlinedReturnNullOverSuppressionCallee(p1); 315*67e74705SXin Li} 316*67e74705SXin Li 317*67e74705SXin Livoid inlinedNullable(Dummy *_Nullable p) { 318*67e74705SXin Li if (p) return; 319*67e74705SXin Li} 320*67e74705SXin Livoid inlinedNonnull(Dummy *_Nonnull p) { 321*67e74705SXin Li if (p) return; 322*67e74705SXin Li} 323*67e74705SXin Livoid inlinedUnspecified(Dummy *p) { 324*67e74705SXin Li if (p) return; 325*67e74705SXin Li} 326*67e74705SXin Li 327*67e74705SXin Livoid testNilReturnWithBlock(Dummy *p) { 328*67e74705SXin Li p = 0; 329*67e74705SXin Li Dummy *_Nonnull (^myblock)(void) = ^Dummy *_Nonnull(void) { 330*67e74705SXin Li return p; // TODO: We should warn in blocks. 331*67e74705SXin Li }; 332*67e74705SXin Li myblock(); 333*67e74705SXin Li} 334*67e74705SXin Li 335*67e74705SXin LiDummy *_Nonnull testDefensiveInlineChecks(Dummy * p) { 336*67e74705SXin Li switch (getRandom()) { 337*67e74705SXin Li case 1: inlinedNullable(p); break; 338*67e74705SXin Li case 2: inlinedNonnull(p); break; 339*67e74705SXin Li case 3: inlinedUnspecified(p); break; 340*67e74705SXin Li } 341*67e74705SXin Li if (getRandom()) 342*67e74705SXin Li takesNonnull(p); // no-warning 343*67e74705SXin Li 344*67e74705SXin Li if (getRandom()) { 345*67e74705SXin Li Dummy *_Nonnull varWithInitializer = p; // no-warning 346*67e74705SXin Li 347*67e74705SXin Li Dummy *_Nonnull var1WithInitializer = p, // no-warning 348*67e74705SXin Li *_Nonnull var2WithInitializer = p; // no-warning 349*67e74705SXin Li } 350*67e74705SXin Li 351*67e74705SXin Li if (getRandom()) { 352*67e74705SXin Li Dummy *_Nonnull varWithoutInitializer; 353*67e74705SXin Li varWithoutInitializer = p; // no-warning 354*67e74705SXin Li } 355*67e74705SXin Li 356*67e74705SXin Li return p; 357*67e74705SXin Li} 358*67e74705SXin Li 359*67e74705SXin Li 360*67e74705SXin Li@interface SomeClass : NSObject { 361*67e74705SXin Li int instanceVar; 362*67e74705SXin Li} 363*67e74705SXin Li@end 364*67e74705SXin Li 365*67e74705SXin Li@implementation SomeClass (MethodReturn) 366*67e74705SXin Li- (id)initWithSomething:(int)i { 367*67e74705SXin Li if (self = [super init]) { 368*67e74705SXin Li instanceVar = i; 369*67e74705SXin Li } 370*67e74705SXin Li 371*67e74705SXin Li return self; 372*67e74705SXin Li} 373*67e74705SXin Li 374*67e74705SXin Li- (TestObject * _Nonnull)testReturnsNullableInNonnullIndirectly { 375*67e74705SXin Li TestObject *local = getNullableTestObject(); 376*67e74705SXin Li return local; // expected-warning {{Nullable pointer is returned from a method that is expected to return a non-null value}} 377*67e74705SXin Li} 378*67e74705SXin Li 379*67e74705SXin Li- (TestObject * _Nonnull)testReturnsCastSuppressedNullableInNonnullIndirectly { 380*67e74705SXin Li TestObject *local = getNullableTestObject(); 381*67e74705SXin Li return (TestObject * _Nonnull)local; // no-warning 382*67e74705SXin Li} 383*67e74705SXin Li 384*67e74705SXin Li- (TestObject * _Nonnull)testReturnsNullableInNonnullWhenPreconditionViolated:(TestObject * _Nonnull) p { 385*67e74705SXin Li TestObject *local = getNullableTestObject(); 386*67e74705SXin Li if (!p) // Pre-condition violated here. 387*67e74705SXin Li return local; // no-warning 388*67e74705SXin Li else 389*67e74705SXin Li return p; // no-warning 390*67e74705SXin Li} 391*67e74705SXin Li@end 392*67e74705SXin Li 393*67e74705SXin Li@interface ClassWithInitializers : NSObject 394*67e74705SXin Li@end 395*67e74705SXin Li 396*67e74705SXin Li@implementation ClassWithInitializers 397*67e74705SXin Li- (instancetype _Nonnull)initWithNonnullReturnAndSelfCheckingIdiom { 398*67e74705SXin Li // This defensive check is a common-enough idiom that we filter don't want 399*67e74705SXin Li // to issue a diagnostic for it, 400*67e74705SXin Li if (self = [super init]) { 401*67e74705SXin Li } 402*67e74705SXin Li 403*67e74705SXin Li return self; // no-warning 404*67e74705SXin Li} 405*67e74705SXin Li 406*67e74705SXin Li- (instancetype _Nonnull)initWithNonnullReturnAndNilReturnViaLocal { 407*67e74705SXin Li self = [super init]; 408*67e74705SXin Li // This leaks, but we're not checking for that here. 409*67e74705SXin Li 410*67e74705SXin Li ClassWithInitializers *other = nil; 411*67e74705SXin Li // False negative. Once we have more subtle suppression of defensive checks in 412*67e74705SXin Li // initializers we should warn here. 413*67e74705SXin Li return other; 414*67e74705SXin Li} 415*67e74705SXin Li@end 416*67e74705SXin Li 417*67e74705SXin Li@interface SubClassWithInitializers : ClassWithInitializers 418*67e74705SXin Li@end 419*67e74705SXin Li 420*67e74705SXin Li@implementation SubClassWithInitializers 421*67e74705SXin Li// Note: Because this is overridding 422*67e74705SXin Li// -[ClassWithInitializers initWithNonnullReturnAndSelfCheckingIdiom], 423*67e74705SXin Li// the return type of this method becomes implicitly id _Nonnull. 424*67e74705SXin Li- (id)initWithNonnullReturnAndSelfCheckingIdiom { 425*67e74705SXin Li if (self = [super initWithNonnullReturnAndSelfCheckingIdiom]) { 426*67e74705SXin Li } 427*67e74705SXin Li 428*67e74705SXin Li return self; // no-warning 429*67e74705SXin Li} 430*67e74705SXin Li 431*67e74705SXin Li- (id _Nonnull)initWithNonnullReturnAndSelfCheckingIdiomV2; { 432*67e74705SXin Li // Another common return-checking idiom 433*67e74705SXin Li self = [super initWithNonnullReturnAndSelfCheckingIdiom]; 434*67e74705SXin Li if (!self) { 435*67e74705SXin Li return nil; // no-warning 436*67e74705SXin Li } 437*67e74705SXin Li 438*67e74705SXin Li return self; 439*67e74705SXin Li} 440*67e74705SXin Li@end 441*67e74705SXin Li 442*67e74705SXin Li@interface ClassWithCopyWithZone : NSObject<NSCopying,NSMutableCopying> { 443*67e74705SXin Li id i; 444*67e74705SXin Li} 445*67e74705SXin Li 446*67e74705SXin Li@end 447*67e74705SXin Li 448*67e74705SXin Li@implementation ClassWithCopyWithZone 449*67e74705SXin Li-(id)copyWithZone:(NSZone *)zone { 450*67e74705SXin Li ClassWithCopyWithZone *newInstance = [[ClassWithCopyWithZone alloc] init]; 451*67e74705SXin Li if (!newInstance) 452*67e74705SXin Li return nil; 453*67e74705SXin Li 454*67e74705SXin Li newInstance->i = i; 455*67e74705SXin Li return newInstance; 456*67e74705SXin Li} 457*67e74705SXin Li 458*67e74705SXin Li-(id)mutableCopyWithZone:(NSZone *)zone { 459*67e74705SXin Li ClassWithCopyWithZone *newInstance = [[ClassWithCopyWithZone alloc] init]; 460*67e74705SXin Li if (newInstance) { 461*67e74705SXin Li newInstance->i = i; 462*67e74705SXin Li } 463*67e74705SXin Li 464*67e74705SXin Li return newInstance; 465*67e74705SXin Li} 466*67e74705SXin Li@end 467*67e74705SXin Li 468*67e74705SXin LiNSString * _Nullable returnsNullableString(); 469*67e74705SXin Li 470*67e74705SXin Livoid callFunctionInSystemHeader() { 471*67e74705SXin Li NSString *s = returnsNullableString(); 472*67e74705SXin Li 473*67e74705SXin Li NSSystemFunctionTakingNonnull(s); 474*67e74705SXin Li #if !NOSYSTEMHEADERS 475*67e74705SXin Li // expected-warning@-2{{Nullable pointer is passed to a callee that requires a non-null 1st parameter}} 476*67e74705SXin Li #endif 477*67e74705SXin Li} 478*67e74705SXin Li 479*67e74705SXin Livoid callMethodInSystemHeader() { 480*67e74705SXin Li NSString *s = returnsNullableString(); 481*67e74705SXin Li 482*67e74705SXin Li NSSystemClass *sc = [[NSSystemClass alloc] init]; 483*67e74705SXin Li [sc takesNonnull:s]; 484*67e74705SXin Li #if !NOSYSTEMHEADERS 485*67e74705SXin Li // expected-warning@-2{{Nullable pointer is passed to a callee that requires a non-null 1st parameter}} 486*67e74705SXin Li #endif 487*67e74705SXin Li} 488*67e74705SXin Li 489*67e74705SXin Li// Test to make sure the analyzer doesn't warn when an a nullability invariant 490*67e74705SXin Li// has already been found to be violated on an instance variable. 491*67e74705SXin Li 492*67e74705SXin Li@class MyInternalClass; 493*67e74705SXin Li@interface MyClass : NSObject { 494*67e74705SXin Li MyInternalClass * _Nonnull _internal; 495*67e74705SXin Li} 496*67e74705SXin Li@end 497*67e74705SXin Li 498*67e74705SXin Li@interface MyInternalClass : NSObject { 499*67e74705SXin Li @public 500*67e74705SXin Li id _someIvar; 501*67e74705SXin Li} 502*67e74705SXin Li-(id _Nonnull)methodWithInternalImplementation; 503*67e74705SXin Li@end 504*67e74705SXin Li 505*67e74705SXin Li@interface MyClass () { 506*67e74705SXin Li MyInternalClass * _Nonnull _nilledOutInternal; 507*67e74705SXin Li} 508*67e74705SXin Li@end 509*67e74705SXin Li 510*67e74705SXin Li@implementation MyClass 511*67e74705SXin Li-(id _Nonnull)methodWithInternalImplementation { 512*67e74705SXin Li if (!_internal) 513*67e74705SXin Li return nil; // no-warning 514*67e74705SXin Li 515*67e74705SXin Li return [_internal methodWithInternalImplementation]; 516*67e74705SXin Li} 517*67e74705SXin Li 518*67e74705SXin Li- (id _Nonnull)methodReturningIvarInImplementation; { 519*67e74705SXin Li return _internal == 0 ? nil : _internal->_someIvar; // no-warning 520*67e74705SXin Li} 521*67e74705SXin Li 522*67e74705SXin Li-(id _Nonnull)methodWithNilledOutInternal { 523*67e74705SXin Li _nilledOutInternal = (id _Nonnull)nil; 524*67e74705SXin Li 525*67e74705SXin Li return nil; // no-warning 526*67e74705SXin Li} 527*67e74705SXin Li@end 528