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