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 6 int getRandom(); 7 8 typedef struct Dummy { int val; } Dummy; 9 10 void takesNullable(Dummy *_Nullable); 11 void takesNonnull(Dummy *_Nonnull); 12 Dummy *_Nullable returnsNullable(); 13 14 void 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 25 Dummy *_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 30 void 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 40 Dummy *_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 54 Dummy *_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 67 void testPreconditionViolationInInlinedFunction(Dummy *p) { 68 doNotWarnWhenPreconditionIsViolated(p); 69 } 70 71 void inlinedNullable(Dummy *_Nullable p) { 72 if (p) return; 73 } 74 void inlinedNonnull(Dummy *_Nonnull p) { 75 if (p) return; 76 } 77 void inlinedUnspecified(Dummy *p) { 78 if (p) return; 79 } 80 81 Dummy *_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 95 TestObject *_Nonnull getNonnullTestObject(); 96 97 void testObjCARCImplicitZeroInitialization() { 98 TestObject * _Nonnull implicitlyZeroInitialized; // no-warning 99 implicitlyZeroInitialized = getNonnullTestObject(); 100 } 101 102 void 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. 109 TestObject * _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 114 TestObject * _Nonnull returnsNilObjCInstanceIndirectlyWithSupressingCast() { 115 TestObject *local = 0; 116 return (TestObject * _Nonnull)local; // no-warning 117 } 118 119 TestObject * _Nonnull returnsNilObjCInstanceDirectly() { 120 return nil; // expected-warning {{Null is returned from a function that is expected to return a non-null value}} 121 } 122 123 TestObject * _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 151 void 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 161 void 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