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