]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/Analysis/nullability_nullonly.mm
Vendor import of clang trunk r300422:
[FreeBSD/FreeBSD.git] / test / Analysis / nullability_nullonly.mm
1 // 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
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 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 {{nil 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 = nil;
111   return local; // expected-warning {{nil returned from a function that is expected to return a non-null value}}
112 }
113
114 TestObject * _Nonnull returnsNilObjCInstanceIndirectlyWithSupressingCast() {
115   TestObject *local = nil;
116   return (TestObject * _Nonnull)local; // no-warning
117 }
118
119 TestObject * _Nonnull returnsNilObjCInstanceDirectly() {
120   return nil; // expected-warning {{nil 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 {{nil 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{{nil 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{{nil passed to a callee that requires a non-null 1st parameter}}
169   #endif
170 }