1 // RUN: %clang_analyze_cc1 -fblocks -verify %s -analyzer-checker=core \
2 // RUN: -analyzer-checker=nullability.NullPassedToNonnull \
3 // RUN: -analyzer-checker=nullability.NullReturnedFromNonnull \
4 // RUN: -analyzer-checker=nullability.NullablePassedToNonnull \
5 // RUN: -analyzer-checker=nullability.NullableReturnedFromNonnull \
6 // RUN: -analyzer-checker=nullability.NullableDereferenced \
7 // RUN: -DNOSYSTEMHEADERS=0
9 // RUN: %clang_analyze_cc1 -fblocks -verify %s -analyzer-checker=core \
10 // RUN: -analyzer-checker=nullability.NullPassedToNonnull \
11 // RUN: -analyzer-checker=nullability.NullReturnedFromNonnull \
12 // RUN: -analyzer-checker=nullability.NullablePassedToNonnull \
13 // RUN: -analyzer-checker=nullability.NullableReturnedFromNonnull \
14 // RUN: -analyzer-checker=nullability.NullableDereferenced \
15 // RUN: -DNOSYSTEMHEADERS=1 \
16 // RUN: -analyzer-config nullability:NoDiagnoseCallsToSystemHeaders=true
18 // RUN: %clang_analyze_cc1 -fblocks -verify %s -analyzer-checker=core\
19 // RUN: -analyzer-checker=nullability.NullPassedToNonnull\
20 // RUN: -analyzer-checker=nullability.NullReturnedFromNonnull\
21 // RUN: -analyzer-checker=nullability.NullablePassedToNonnull\
22 // RUN: -analyzer-checker=nullability.NullableReturnedFromNonnull\
23 // RUN: -analyzer-checker=nullability.NullableDereferenced\
24 // RUN: -DNOSYSTEMHEADERS=0 -fobjc-arc
26 // RUN: %clang_analyze_cc1 -fblocks -verify %s -analyzer-checker=core\
27 // RUN: -analyzer-checker=nullability.NullPassedToNonnull\
28 // RUN: -analyzer-checker=nullability.NullReturnedFromNonnull\
29 // RUN: -analyzer-checker=nullability.NullablePassedToNonnull\
30 // RUN: -analyzer-checker=nullability.NullableReturnedFromNonnull\
31 // RUN: -analyzer-checker=nullability.NullableDereferenced\
32 // RUN: -DNOSYSTEMHEADERS=1 -fobjc-arc\
33 // RUN: -analyzer-config nullability:NoDiagnoseCallsToSystemHeaders=true
35 #include "Inputs/system-header-simulator-for-nullability.h"
37 extern void __assert_fail(__const char *__assertion, __const char *__file,
38 unsigned int __line, __const char *__function)
39 __attribute__((__noreturn__));
41 #define assert(expr) \
42 ((expr) ? (void)(0) : __assert_fail(#expr, __FILE__, __LINE__, __func__))
44 @interface TestObject : NSObject
45 - (int *_Nonnull)returnsNonnull;
46 - (int *_Nullable)returnsNullable;
47 - (int *)returnsUnspecified;
48 - (void)takesNonnull:(int *_Nonnull)p;
49 - (void)takesNonnullBlock:(void (^ _Nonnull)(void))block;
50 - (void)takesNullable:(int *_Nullable)p;
51 - (void)takesUnspecified:(int *)p;
52 @property(readonly, strong) NSString *stuff;
53 @property(readonly, nonnull) int *propReturnsNonnull;
54 @property(readonly, nonnull) void (^propReturnsNonnullBlock)(void);
55 @property(readonly, nullable) void (^propReturnsNullableBlock)(void);
56 @property(readonly, nullable) int *propReturnsNullable;
57 @property(readonly) int *propReturnsUnspecified;
58 + (nullable TestObject *)getNullableObject;
61 TestObject * getUnspecifiedTestObject();
62 TestObject *_Nonnull getNonnullTestObject();
63 TestObject *_Nullable getNullableTestObject();
67 typedef struct Dummy { int val; } Dummy;
69 void takesNullable(Dummy *_Nullable);
70 void takesNonnull(Dummy *_Nonnull);
71 void takesUnspecified(Dummy *);
72 void takesNonnullBlock(void (^ _Nonnull)(void));
73 void takesNonnullObject(NSObject *_Nonnull);
75 Dummy *_Nullable returnsNullable();
76 Dummy *_Nonnull returnsNonnull();
77 Dummy *returnsUnspecified();
78 int *_Nullable returnsNullableInt();
80 template <typename T> T *eraseNullab(T *p) { return p; }
82 void takesAttrNonnull(Dummy *p) __attribute((nonnull(1)));
84 void testBasicRules() {
85 Dummy *p = returnsNullable();
86 int *ptr = returnsNullableInt();
87 // Make every dereference a different path to avoid sinks after errors.
88 switch (getRandom()) {
90 Dummy &r = *p; // expected-warning {{Nullable pointer is dereferenced}}
93 int b = p->val; // expected-warning {{Nullable pointer is dereferenced}}
96 int stuff = *ptr; // expected-warning {{Nullable pointer is dereferenced}}
99 takesNonnull(p); // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
107 case 5: takesAttrNonnull(p); break; // expected-warning {{Nullable pointer is passed to}}
108 default: { Dummy d = *p; } break; // expected-warning {{Nullable pointer is dereferenced}}
121 takesNonnull(q); // expected-warning {{Null passed to a callee that requires a non-null 1st parameter}}
124 Dummy *_Nonnull nonnull = &a;
125 nonnull = q; // expected-warning {{Null assigned to a pointer which is expected to have non-null value}}
131 void testMultiParamChecking(Dummy *_Nonnull a, Dummy *_Nullable b,
134 void testArgumentTracking(Dummy *_Nonnull nonnull, Dummy *_Nullable nullable) {
137 switch(getRandom()) {
138 case 1: nonnull = p; break; // expected-warning {{Nullable pointer is assigned to a pointer which is expected to have non-null value}}
139 case 2: p = 0; break;
140 case 3: q = p; break;
141 case 4: testMultiParamChecking(nonnull, nullable, nonnull); break;
142 case 5: testMultiParamChecking(nonnull, nonnull, nonnull); break;
143 case 6: testMultiParamChecking(nonnull, nullable, nullable); break; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 3rd parameter}}
144 case 7: testMultiParamChecking(nullable, nullable, nonnull); // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
145 case 8: testMultiParamChecking(nullable, nullable, nullable); // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
146 case 9: testMultiParamChecking((Dummy *_Nonnull)0, nullable, nonnull); break;
150 void testArgumentTrackingDirectly(Dummy *_Nonnull nonnull, Dummy *_Nullable nullable) {
151 switch(getRandom()) {
152 case 1: testMultiParamChecking(nonnull, nullable, nonnull); break;
153 case 2: testMultiParamChecking(nonnull, nonnull, nonnull); break;
154 case 3: testMultiParamChecking(nonnull, nullable, nullable); break; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 3rd parameter}}
155 case 4: testMultiParamChecking(nullable, nullable, nonnull); // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
156 case 5: testMultiParamChecking(nullable, nullable, nullable); // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
157 case 6: testMultiParamChecking((Dummy *_Nonnull)0, nullable, nonnull); break;
161 Dummy *_Nonnull testNullableReturn(Dummy *_Nullable a) {
163 return p; // expected-warning {{Nullable pointer is returned from a function that is expected to return a non-null value}}
166 Dummy *_Nonnull testNullReturn() {
168 return p; // expected-warning {{Null returned from a function that is expected to return a non-null value}}
171 void testObjCMessageResultNullability() {
172 // The expected result: the most nullable of self and method return type.
173 TestObject *o = getUnspecifiedTestObject();
174 int *shouldBeNullable = [eraseNullab(getNullableTestObject()) returnsNonnull];
175 switch (getRandom()) {
177 // The core analyzer assumes that the receiver is non-null after a message
178 // send. This is to avoid some false positives, and increase performance
179 // but it also reduces the coverage and makes this checker unable to reason
180 // about the nullness of the receiver.
181 [o takesNonnull:shouldBeNullable]; // No warning expected.
185 [eraseNullab(getNullableTestObject()) returnsUnspecified];
186 [o takesNonnull:shouldBeNullable]; // No warning expected.
189 shouldBeNullable = [eraseNullab(getNullableTestObject()) returnsNullable];
190 [o takesNonnull:shouldBeNullable]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
193 shouldBeNullable = [eraseNullab(getNonnullTestObject()) returnsNullable];
194 [o takesNonnull:shouldBeNullable]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
198 [eraseNullab(getUnspecifiedTestObject()) returnsNullable];
199 [o takesNonnull:shouldBeNullable]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
202 shouldBeNullable = [eraseNullab(getNullableTestObject()) returnsNullable];
203 [o takesNonnull:shouldBeNullable]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
206 int *shouldBeNonnull = [eraseNullab(getNonnullTestObject()) returnsNonnull];
207 [o takesNonnull:shouldBeNonnull];
212 void testObjCPropertyReadNullability() {
213 TestObject *o = getNonnullTestObject();
214 switch (getRandom()) {
216 [o takesNonnull:o.propReturnsNonnull]; // no-warning
217 [o takesNonnullBlock:o.propReturnsNonnullBlock]; // no-warning
220 [o takesNonnull:o.propReturnsUnspecified]; // no-warning
223 [o takesNonnull:o.propReturnsNullable]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
226 // If a property is constrained nonnull, assume it remains nonnull
227 if (o.propReturnsNullable) {
228 [o takesNonnull:o.propReturnsNullable]; // no-warning
229 [o takesNonnull:o.propReturnsNullable]; // no-warning
233 if (!o.propReturnsNullable) {
234 [o takesNonnull:o.propReturnsNullable]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
238 if (!o.propReturnsNullable) {
239 if (o.propReturnsNullable) {
240 // Nonnull constraint from the more recent call wins
241 [o takesNonnull:o.propReturnsNullable]; // no-warning
246 // Constraints on property return values are receiver-qualified
247 if (o.propReturnsNullable) {
248 [o takesNonnull:o.propReturnsNullable]; // no-warning
249 [o takesNonnull:getNonnullTestObject().propReturnsNullable]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
253 // Assertions must be effective at suppressing warnings
254 assert(o.propReturnsNullable);
255 [o takesNonnull:o.propReturnsNullable]; // no-warning
258 [o takesNonnullBlock:o.propReturnsNullableBlock]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
261 [o takesNonnull:getNullableTestObject().propReturnsNonnull]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
264 [o takesNonnull:[TestObject getNullableObject].propReturnsNonnull]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
269 Dummy * _Nonnull testDirectCastNullableToNonnull() {
270 Dummy *p = returnsNullable();
271 takesNonnull((Dummy * _Nonnull)p); // no-warning
272 return (Dummy * _Nonnull)p; // no-warning
275 Dummy * _Nonnull testIndirectCastNullableToNonnull() {
276 Dummy *p = (Dummy * _Nonnull)returnsNullable();
277 takesNonnull(p); // no-warning
278 return p; // no-warning
281 Dummy * _Nonnull testDirectCastNilToNonnull() {
282 takesNonnull((Dummy * _Nonnull)0); // no-warning
283 return (Dummy * _Nonnull)0; // no-warning
286 void testImplicitCastNilToNonnull() {
288 takesNonnullObject(obj); // expected-warning {{nil passed to a callee that requires a non-null 1st parameter}}
291 void testImplicitCastNullableArgToNonnull(TestObject *_Nullable obj) {
293 takesNonnullObject(obj); // expected-warning {{nil passed to a callee that requires a non-null 1st parameter}}
297 void testIndirectCastNilToNonnullAndPass() {
298 Dummy *p = (Dummy * _Nonnull)0;
299 // FIXME: Ideally the cast above would suppress this warning.
300 takesNonnull(p); // expected-warning {{Null passed to a callee that requires a non-null 1st parameter}}
303 void testDirectCastNilToNonnullAndAssignToLocalInInitializer() {
304 Dummy * _Nonnull nonnullLocalWithAssignmentInInitializer = (Dummy * _Nonnull)0; // no-warning
305 (void)nonnullLocalWithAssignmentInInitializer;
307 // Since we've already had an invariant violation along this path,
308 // we shouldn't warn here.
309 nonnullLocalWithAssignmentInInitializer = 0;
310 (void)nonnullLocalWithAssignmentInInitializer;
314 void testDirectCastNilToNonnullAndAssignToLocal(Dummy * _Nonnull p) {
315 Dummy * _Nonnull nonnullLocalWithAssignment = p;
316 nonnullLocalWithAssignment = (Dummy * _Nonnull)0; // no-warning
317 (void)nonnullLocalWithAssignment;
319 // Since we've already had an invariant violation along this path,
320 // we shouldn't warn here.
321 nonnullLocalWithAssignment = 0;
322 (void)nonnullLocalWithAssignment;
325 void testDirectCastNilToNonnullAndAssignToParam(Dummy * _Nonnull p) {
326 p = (Dummy * _Nonnull)0; // no-warning
329 @interface ClassWithNonnullIvar : NSObject {
334 @implementation ClassWithNonnullIvar
335 -(void)testDirectCastNilToNonnullAndAssignToIvar {
336 _nonnullIvar = (Dummy * _Nonnull)0; // no-warning;
338 // Since we've already had an invariant violation along this path,
339 // we shouldn't warn here.
344 void testIndirectNilPassToNonnull() {
346 takesNonnull(p); // expected-warning {{Null passed to a callee that requires a non-null 1st parameter}}
349 void testBlockIndirectNilPassToNonnull() {
350 void (^p)(void) = nil;
351 takesNonnullBlock(p); // expected-warning {{Null passed to a callee that requires a non-null 1st parameter}}
354 void testConditionalNilPassToNonnull(Dummy *p) {
356 takesNonnull(p); // expected-warning {{Null passed to a callee that requires a non-null 1st parameter}}
360 Dummy * _Nonnull testIndirectCastNilToNonnullAndReturn() {
361 Dummy *p = (Dummy * _Nonnull)0;
362 // FIXME: Ideally the cast above would suppress this warning.
363 return p; // expected-warning {{Null returned from a function that is expected to return a non-null value}}
366 void testInvalidPropagation() {
367 Dummy *p = returnsUnspecified();
372 void onlyReportFirstPreconditionViolationOnPath() {
373 Dummy *p = returnsNullable();
374 takesNonnull(p); // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
375 takesNonnull(p); // No warning.
376 // The first warning was not a sink. The analysis expected to continue.
378 i = 5 / i; // expected-warning {{Division by zero}}
382 Dummy *_Nonnull doNotWarnWhenPreconditionIsViolatedInTopFunc(
386 0; // avoid compiler warning (which is not generated by the analyzer)
388 return ret; // no warning
390 return p; // no warning
396 Dummy *_Nonnull doNotWarnWhenPreconditionIsViolated(Dummy *_Nonnull p) {
399 0; // avoid compiler warning (which is not generated by the analyzer)
401 return ret; // no warning
403 return p; // no warning
409 void testPreconditionViolationInInlinedFunction(Dummy *p) {
410 doNotWarnWhenPreconditionIsViolated(p);
413 @interface TestInlinedPreconditionViolationClass : NSObject
416 @implementation TestInlinedPreconditionViolationClass
417 -(Dummy * _Nonnull) calleeWithParam:(Dummy * _Nonnull) p2 {
419 if (!p2) // p2 binding becomes dead at this point.
420 return x; // no-warning
425 -(Dummy *)callerWithParam:(Dummy * _Nonnull) p1 {
426 return [self calleeWithParam:p1];
431 int * _Nonnull InlinedPreconditionViolationInFunctionCallee(int * _Nonnull p2) {
433 if (!p2) // p2 binding becomes dead at this point.
434 return x; // no-warning
439 int * _Nonnull InlinedReturnNullOverSuppressionCallee(int * _Nonnull p2) {
441 return result; // no-warning; but this is an over suppression
444 int *InlinedReturnNullOverSuppressionCaller(int * _Nonnull p1) {
445 return InlinedReturnNullOverSuppressionCallee(p1);
448 void inlinedNullable(Dummy *_Nullable p) {
451 void inlinedNonnull(Dummy *_Nonnull p) {
454 void inlinedUnspecified(Dummy *p) {
458 void testNilReturnWithBlock(Dummy *p) {
460 Dummy *_Nonnull (^myblock)(void) = ^Dummy *_Nonnull(void) {
461 return p; // TODO: We should warn in blocks.
466 Dummy *_Nonnull testDefensiveInlineChecks(Dummy * p) {
467 switch (getRandom()) {
468 case 1: inlinedNullable(p); break;
469 case 2: inlinedNonnull(p); break;
470 case 3: inlinedUnspecified(p); break;
473 takesNonnull(p); // no-warning
476 Dummy *_Nonnull varWithInitializer = p; // no-warning
478 Dummy *_Nonnull var1WithInitializer = p, // no-warning
479 *_Nonnull var2WithInitializer = p; // no-warning
483 Dummy *_Nonnull varWithoutInitializer;
484 varWithoutInitializer = p; // no-warning
491 @interface SomeClass : NSObject {
496 @implementation SomeClass (MethodReturn)
497 - (id)initWithSomething:(int)i {
498 if (self = [super init]) {
505 - (TestObject * _Nonnull)testReturnsNullableInNonnullIndirectly {
506 TestObject *local = getNullableTestObject();
507 return local; // expected-warning {{Nullable pointer is returned from a method that is expected to return a non-null value}}
510 - (TestObject * _Nonnull)testReturnsCastSuppressedNullableInNonnullIndirectly {
511 TestObject *local = getNullableTestObject();
512 return (TestObject * _Nonnull)local; // no-warning
515 - (TestObject * _Nonnull)testReturnsNullableInNonnullWhenPreconditionViolated:(TestObject * _Nonnull) p {
516 TestObject *local = getNullableTestObject();
517 if (!p) // Pre-condition violated here.
518 return local; // no-warning
520 return p; // no-warning
524 @interface ClassWithInitializers : NSObject
527 @implementation ClassWithInitializers
528 - (instancetype _Nonnull)initWithNonnullReturnAndSelfCheckingIdiom {
529 // This defensive check is a common-enough idiom that we filter don't want
530 // to issue a diagnostic for it,
531 if (self = [super init]) {
534 return self; // no-warning
537 - (instancetype _Nonnull)initWithNonnullReturnAndNilReturnViaLocal {
539 // This leaks, but we're not checking for that here.
541 ClassWithInitializers *other = nil;
542 // False negative. Once we have more subtle suppression of defensive checks in
543 // initializers we should warn here.
548 @interface SubClassWithInitializers : ClassWithInitializers
551 @implementation SubClassWithInitializers
552 // Note: Because this is overriding
553 // -[ClassWithInitializers initWithNonnullReturnAndSelfCheckingIdiom],
554 // the return type of this method becomes implicitly id _Nonnull.
555 - (id)initWithNonnullReturnAndSelfCheckingIdiom {
556 if (self = [super initWithNonnullReturnAndSelfCheckingIdiom]) {
559 return self; // no-warning
562 - (id _Nonnull)initWithNonnullReturnAndSelfCheckingIdiomV2; {
563 // Another common return-checking idiom
564 self = [super initWithNonnullReturnAndSelfCheckingIdiom];
566 return nil; // no-warning
573 @interface ClassWithCopyWithZone : NSObject<NSCopying,NSMutableCopying> {
579 @implementation ClassWithCopyWithZone
580 -(id)copyWithZone:(NSZone *)zone {
581 ClassWithCopyWithZone *newInstance = [[ClassWithCopyWithZone alloc] init];
589 -(id)mutableCopyWithZone:(NSZone *)zone {
590 ClassWithCopyWithZone *newInstance = [[ClassWithCopyWithZone alloc] init];
599 NSString * _Nullable returnsNullableString();
601 void callFunctionInSystemHeader() {
602 NSString *s = returnsNullableString();
604 NSSystemFunctionTakingNonnull(s);
606 // expected-warning@-2{{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
610 void callMethodInSystemHeader() {
611 NSString *s = returnsNullableString();
613 NSSystemClass *sc = [[NSSystemClass alloc] init];
616 // expected-warning@-2{{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
620 // Test to make sure the analyzer doesn't warn when an a nullability invariant
621 // has already been found to be violated on an instance variable.
623 @class MyInternalClass;
624 @interface MyClass : NSObject {
625 MyInternalClass * _Nonnull _internal;
629 @interface MyInternalClass : NSObject {
633 -(id _Nonnull)methodWithInternalImplementation;
636 @interface MyClass () {
637 MyInternalClass * _Nonnull _nilledOutInternal;
641 @implementation MyClass
642 -(id _Nonnull)methodWithInternalImplementation {
644 return nil; // no-warning
646 return [_internal methodWithInternalImplementation];
649 - (id _Nonnull)methodReturningIvarInImplementation; {
650 return _internal == 0 ? nil : _internal->_someIvar; // no-warning
653 -(id _Nonnull)methodWithNilledOutInternal {
654 _nilledOutInternal = (id _Nonnull)nil;
656 return nil; // no-warning