xref: /llvm-project/clang/test/Analysis/ctor-bug-path.cpp (revision a11e51e91f73e413eb044bc0b2f2e205735618d7)
1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-output=text -std=c++11 -verify %s
2 // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-output=text -std=c++17 -verify %s
3 
4 #include "Inputs/system-header-simulator-cxx.h"
5 
6 namespace copyMoveTrackCtor {
7 struct S {
8   int *p1, *p2;
ScopyMoveTrackCtor::S9   S(int *a, int *b) : p1(a), p2(b) {} // expected-note{{Null pointer value stored to 's.p1'}}
10 };
11 
CtorDirect()12 void CtorDirect() {
13   int *x = nullptr, *y = nullptr;
14   // expected-note@-1{{'x' initialized to a null pointer value}}
15 
16   S s(x, y);
17   // expected-note@-1{{Passing null pointer value via 1st parameter 'a'}}
18   // expected-note@-2{{Calling constructor for 'S'}}
19   // expected-note@-3{{Returning from constructor for 'S'}}
20   // expected-note@-4{{'s' initialized here}}
21   S s2 = s; // expected-note{{Null pointer value stored to 's2.p1'}}
22   // expected-note@-1{{'s2' initialized here}}
23   S s3 = s2;  // expected-note{{Null pointer value stored to 's3.p1'}}
24   // expected-note@-1{{'s3' initialized here}}
25   S s4 = std::move(s3); // expected-note{{Null pointer value stored to 's4.p1'}}
26   // expected-note@-1{{'s4' initialized here}}
27   S s5 = s4; // expected-note{{Null pointer value stored to 's5.p1'}}
28 
29   int i = *s5.p1; // expected-warning{{Dereference of null pointer}}
30   // expected-note@-1{{Dereference of null pointer (loaded from field 'p1')}}
31 
32   (void) i;
33 }
34 } // namespace copyMoveTrackCtor
35 
36 namespace copyMoveTrackInitList {
37 struct S {
38   int *p1, *p2;
39 };
40 
InitListDirect()41 void InitListDirect() {
42   int *x = nullptr, *y = nullptr; //expected-note{{'x' initialized to a null pointer value}}
43 
44   S s{x, y}; //expected-note{{'s.p1' initialized to a null pointer value}}
45   //expected-note@-1{{'s' initialized here}}
46   S s2 = s; // expected-note{{Null pointer value stored to 's2.p1'}}
47   // expected-note@-1{{'s2' initialized here}}
48   S s3 = s2; // expected-note{{Null pointer value stored to 's3.p1'}}
49   // expected-note@-1{{'s3' initialized here}}
50   S s4 = std::move(s3); // expected-note{{Null pointer value stored to 's4.p1'}}
51   // expected-note@-1{{'s4' initialized here}}
52   S s5 = s4; // expected-note{{Null pointer value stored to 's5.p1'}}
53 
54   int i = *s5.p1; // expected-warning{{Dereference of null pointer}}
55   // expected-note@-1{{Dereference of null pointer (loaded from field 'p1')}}
56 
57   (void) i;
58 }
59 
InitListAssign()60 void InitListAssign() {
61   int *x = nullptr, *y = nullptr; //expected-note{{'x' initialized to a null pointer value}}
62 
63   S s = {x, y}; //expected-note{{'s.p1' initialized to a null pointer value}}
64   //expected-note@-1{{'s' initialized here}}
65   S s2 = s; // expected-note{{Null pointer value stored to 's2.p1'}}
66   // expected-note@-1{{'s2' initialized here}}
67   S s3 = s2; // expected-note{{Null pointer value stored to 's3.p1'}}
68   // expected-note@-1{{'s3' initialized here}}
69   S s4 = std::move(s3); // expected-note{{Null pointer value stored to 's4.p1'}}
70   // expected-note@-1{{'s4' initialized here}}
71   S s5 = s4; // expected-note{{Null pointer value stored to 's5.p1'}}
72 
73   int i = *s5.p1; // expected-warning{{Dereference of null pointer}}
74   // expected-note@-1{{Dereference of null pointer (loaded from field 'p1')}}
75 
76   (void) i;
77 }
78 
79 } // namespace copyMoveTrackInitList
80 
81 namespace copyMoveTrackCtorMemberInitList {
82 struct S {
83   int *p1, *p2;
ScopyMoveTrackCtorMemberInitList::S84   S(int *a, int *b) : p1{a}, p2{b} {} // expected-note{{Null pointer value stored to 's.p1'}}
85 };
86 
CtorDirect()87 void CtorDirect() {
88   int *x = nullptr, *y = nullptr;
89   // expected-note@-1{{'x' initialized to a null pointer value}}
90 
91   S s{x, y};
92   // expected-note@-1{{Passing null pointer value via 1st parameter 'a'}}
93   // expected-note@-2{{Calling constructor for 'S'}}
94   // expected-note@-3{{Returning from constructor for 'S'}}
95   // expected-note@-4{{'s' initialized here}}
96   S s2 = s; // expected-note{{Null pointer value stored to 's2.p1'}}
97   // expected-note@-1{{'s2' initialized here}}
98   S s3 = s2;  // expected-note{{Null pointer value stored to 's3.p1'}}
99   // expected-note@-1{{'s3' initialized here}}
100   S s4 = std::move(s3); // expected-note{{Null pointer value stored to 's4.p1'}}
101   // expected-note@-1{{'s4' initialized here}}
102   S s5 = s4; // expected-note{{Null pointer value stored to 's5.p1'}}
103 
104   int i = *s5.p1; // expected-warning{{Dereference of null pointer}}
105   // expected-note@-1{{Dereference of null pointer (loaded from field 'p1')}}
106 
107   (void) i;
108 }
109 } // namespace copyMoveTrackCtorMemberInitList
110 
111 namespace directInitList {
112 struct S {
113   int *p1, *p2;
114 };
115 
InitListDirect()116 void InitListDirect() {
117   int *x = nullptr, *y = nullptr; //expected-note{{'y' initialized to a null pointer value}}
118 
119   S s{x, y}; //expected-note{{'s.p2' initialized to a null pointer value}}
120 
121   int i = *s.p2; // expected-warning{{Dereference of null pointer}}
122   // expected-note@-1{{Dereference of null pointer}}
123   (void) i;
124 }
125 } // namespace directInitList
126 
127 namespace directNestedInitList {
128 struct S2 {
129   int *p1, *p2;
130 };
131 
132 struct S {
133   S2 s;
134 };
135 
InitListNestedDirect()136 void InitListNestedDirect() {
137   int *x = nullptr, *y = nullptr; //expected-note{{'y' initialized to a null pointer value}}
138 
139   //FIXME: Put more information to the notes.
140   S s{x, y}; //expected-note{{'s.s.p2' initialized to a null pointer value}}
141 
142   int i = *s.s.p2; // expected-warning{{Dereference of null pointer}}
143   // expected-note@-1{{Dereference of null pointer}}
144   (void) i;
145 }
146 } // namespace directNestedInitList
147 
148 #if __cplusplus >= 201703L
149 
150 namespace structuredBinding {
151 struct S {
152   int *p1, *p2;
153 };
154 
StructuredBinding()155 void StructuredBinding() {
156   int *x = nullptr, *y = nullptr;
157   //expected-note@-1{{'y' initialized to a null pointer value}}
158 
159   S s{x, y};
160   //expected-note@-1{{'s.p2' initialized to a null pointer value}}
161   //expected-note@-2{{'s' initialized here}}
162 
163   auto [a, b] = s; //expected-note{{Null pointer value stored to '.p2'}}
164 
165   int i = *b; // expected-warning{{Dereference of null pointer}}
166   // expected-note@-1{{Dereference of null pointer}}
167   (void) i;
168 }
169 } // namespace structuredBinding
170 
171 #endif
172 
173 namespace nestedCtorInitializer {
174   struct S5{
175     int *x, *y;
176   };
177 
178   struct S4 {
179     S5 s5;
180   };
181 
182   struct S3 {
183     S4 s4;
184   };
185 
186   struct S2 {
187     S3 s3;
188   };
189 
190   struct S {
191     S2 s2;
192 
193     //FIXME: Put more information to the notes.
SnestedCtorInitializer::S194     S(int *x, int *y) : s2{x, y} {};
195     // expected-note@-1{{Null pointer value stored to 's.s2.s3.s4.s5.y'}}
196   };
197 
nestedCtorInit()198   void nestedCtorInit(){
199     int *x = nullptr, *y = nullptr; // expected-note{{'y' initialized to a null pointer value}}
200 
201     S s{x,y};
202     // expected-note@-1{{Passing null pointer value via 2nd parameter}}
203     // expected-note@-2{{Calling constructor for 'S'}}
204     // expected-note@-3{{Returning from constructor for 'S'}}
205 
206     int i = *s.s2.s3.s4.s5.y; // expected-warning{{Dereference of null pointer}}
207     // expected-note@-1{{Dereference of null pointer}}
208     (void) i;
209   }
210 } // namespace nestedCtorInitializer
211 
212 namespace NestedRegionTrack {
213 struct N {
214   int *e;
215 };
216 
217 struct S {
218   N y;
219 };
220 
NestedRegionTrack()221 void NestedRegionTrack() {
222   int *x = nullptr, *y = nullptr;
223   // expected-note@-1{{'y' initialized to a null pointer value}}
224 
225   // Test for nested single element initializer list here.
226   S a{{{{{{{{y}}}}}}}};
227   // expected-note@-1{{'a.y.e' initialized to a null pointer value}}
228   // expected-note@-2{{'a' initialized here}}
229   // expected-warning@-3{{too many braces around scalar initializer}}
230   // expected-warning@-4{{too many braces around scalar initializer}}
231   // expected-warning@-5{{too many braces around scalar initializer}}
232   // expected-warning@-6{{too many braces around scalar initializer}}
233   // expected-warning@-7{{too many braces around scalar initializer}}
234 
235   S b = a; // expected-note{{Null pointer value stored to 'b.y.e'}}
236 
237   int i = *b.y.e;
238   // expected-warning@-1{{Dereference of null pointer}}
239   // expected-note@-2{{Dereference of null pointer}}
240   (void) i;
241   (void) x;
242 }
243 
244 } // namespace NestedRegionTrack
245 
246 namespace NestedElementRegionTrack {
247 struct N {
248   int *arr[2];
249 };
250 
251 struct S {
252   N n;
253 };
254 
NestedElementRegionTrack()255 void NestedElementRegionTrack() {
256   int *x = nullptr, *y = nullptr;
257   // expected-note@-1{{'y' initialized to a null pointer value}}
258 
259   S a{{x, y}};
260   // expected-note@-1{{Initializing to a null pointer value}}
261   // expected-note@-2{{'a' initialized here}}
262 
263   S b = a; // expected-note{{Storing null pointer value}}
264 
265   int i = *b.n.arr[1];
266   // expected-warning@-1{{Dereference of null pointer}}
267   // expected-note@-2{{Dereference of null pointer}}
268   (void) i;
269 }
270 
271 } // namespace NestedElementRegionTrack
272