blob: 18225391ee8728776dbc1113714508b33193b484 [file] [log] [blame]
Dominic Chen184c6242017-03-03 18:02:02 +00001// RUN: %clang_analyze_cc1 -fobjc-arc -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull -DNOSYSTEMHEADERS=0 -verify %s
2// RUN: %clang_analyze_cc1 -fobjc-arc -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull -analyzer-config nullability:NoDiagnoseCallsToSystemHeaders=true -DNOSYSTEMHEADERS=1 -verify %s
Gabor Horvath29307352015-09-14 18:31:34 +00003
Devin Coughlina1d9d752016-03-05 01:32:43 +00004#include "Inputs/system-header-simulator-for-nullability.h"
Devin Coughlin851da712016-01-15 21:35:40 +00005
Gabor Horvath29307352015-09-14 18:31:34 +00006int 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);
Anna Zaksad9e7ea2016-01-29 18:43:15 +000021 takesNonnull(q); // expected-warning {{Null passed to a callee that requires a non-null 1st parameter}}
Gabor Horvath29307352015-09-14 18:31:34 +000022 }
23}
24
25Dummy *_Nonnull testNullReturn() {
26 Dummy *p = 0;
Anna Zaks6d4e76b2016-12-15 22:55:15 +000027 return p; // expected-warning {{Null returned from a function that is expected to return a non-null value}}
Gabor Horvath29307352015-09-14 18:31:34 +000028}
29
30void onlyReportFirstPreconditionViolationOnPath() {
31 Dummy *p = 0;
Anna Zaksad9e7ea2016-01-29 18:43:15 +000032 takesNonnull(p); // expected-warning {{Null passed to a callee that requires a non-null 1st parameter}}
Gabor Horvath29307352015-09-14 18:31:34 +000033 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}
Devin Coughlin851da712016-01-15 21:35:40 +000091
Devin Coughlin5a3843e2016-01-18 18:53:33 +000092@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() {
Anna Zaks6d4e76b2016-12-15 22:55:15 +0000103 TestObject * _Nonnull explicitlyZeroInitialized = nil; // expected-warning {{nil assigned to a pointer which is expected to have non-null value}}
Devin Coughlin5a3843e2016-01-18 18:53:33 +0000104}
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() {
Anna Zaks6d4e76b2016-12-15 22:55:15 +0000110 TestObject *local = nil;
111 return local; // expected-warning {{nil returned from a function that is expected to return a non-null value}}
Devin Coughlin5a3843e2016-01-18 18:53:33 +0000112}
113
114TestObject * _Nonnull returnsNilObjCInstanceIndirectlyWithSupressingCast() {
Anna Zaks6d4e76b2016-12-15 22:55:15 +0000115 TestObject *local = nil;
Devin Coughlin5a3843e2016-01-18 18:53:33 +0000116 return (TestObject * _Nonnull)local; // no-warning
117}
118
119TestObject * _Nonnull returnsNilObjCInstanceDirectly() {
Anna Zaks6d4e76b2016-12-15 22:55:15 +0000120 return nil; // expected-warning {{nil returned from a function that is expected to return a non-null value}}
Devin Coughlin5a3843e2016-01-18 18:53:33 +0000121}
122
123TestObject * _Nonnull returnsNilObjCInstanceDirectlyWithSuppressingCast() {
124 return (TestObject * _Nonnull)nil; // no-warning
125}
Devin Coughlin851da712016-01-15 21:35:40 +0000126
127@interface SomeClass : NSObject
128@end
129
130@implementation SomeClass (MethodReturn)
131- (SomeClass * _Nonnull)testReturnsNilInNonnull {
132 SomeClass *local = nil;
Anna Zaks6d4e76b2016-12-15 22:55:15 +0000133 return local; // expected-warning {{nil returned from a method that is expected to return a non-null value}}
Devin Coughlin851da712016-01-15 21:35:40 +0000134}
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
Devin Coughlina1d9d752016-03-05 01:32:43 +0000149
150
151void callFunctionInSystemHeader() {
152 NSString *s;
153 s = nil;
154
155 NSSystemFunctionTakingNonnull(s);
156 #if !NOSYSTEMHEADERS
Anna Zaks6d4e76b2016-12-15 22:55:15 +0000157 // expected-warning@-2{{nil passed to a callee that requires a non-null 1st parameter}}
Devin Coughlina1d9d752016-03-05 01:32:43 +0000158 #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
Anna Zaks6d4e76b2016-12-15 22:55:15 +0000168 // expected-warning@-2{{nil passed to a callee that requires a non-null 1st parameter}}
Devin Coughlina1d9d752016-03-05 01:32:43 +0000169 #endif
170}