@@ -119,20 +119,18 @@ namespace variable_declaration_in_condition {
119
119
bool coin ();
120
120
121
121
bool foo () {
122
- return coin (); // tracking-note{{Returning value}}
122
+ return coin ();
123
123
}
124
124
125
125
int bar;
126
126
127
127
void test () {
128
128
int *x = 0 ; // expected-note{{'x' initialized to a null pointer value}}
129
129
130
- if (int flag = foo ()) // tracking-note{{Calling 'foo'}}
131
- // tracking-note@-1{{Returning from 'foo'}}
132
- // tracking-note@-2{{'flag' initialized here}}
133
- // debug-note@-3{{Tracking condition 'flag'}}
134
- // expected-note@-4{{Assuming 'flag' is not equal to 0}}
135
- // expected-note@-5{{Taking true branch}}
130
+ if (int flag = foo ()) // tracking-note{{'flag' initialized here}}
131
+ // debug-note@-1{{Tracking condition 'flag'}}
132
+ // expected-note@-2{{Assuming 'flag' is not equal to 0}}
133
+ // expected-note@-3{{Taking true branch}}
136
134
137
135
*x = 5 ; // expected-warning{{Dereference of null pointer}}
138
136
// expected-note@-1{{Dereference of null pointer}}
@@ -143,39 +141,114 @@ namespace conversion_to_bool {
143
141
bool coin ();
144
142
145
143
struct ConvertsToBool {
146
- operator bool () const { return coin (); } // tracking-note{{Returning value}}
144
+ operator bool () const { return coin (); }
147
145
};
148
146
149
147
void test () {
150
148
int *x = 0 ; // expected-note{{'x' initialized to a null pointer value}}
151
149
152
150
if (ConvertsToBool ())
153
- // tracking-note@-1 {{Calling 'ConvertsToBool::operator bool'}}
154
- // tracking-note@-2{{Returning from 'ConvertsToBool::operator bool'}}
155
- // debug-note@-3{{Tracking condition 'ConvertsToBool()'}}
156
- // expected-note@-4{{Assuming the condition is true}}
157
- // expected-note@-5{{Taking true branch}}
151
+ // debug-note@-1{{Tracking condition 'ConvertsToBool()'}}
152
+ // expected-note@-2{{Assuming the condition is true}}
153
+ // expected-note@-3{{Taking true branch}}
158
154
*x = 5 ; // expected-warning{{Dereference of null pointer}}
159
155
// expected-note@-1{{Dereference of null pointer}}
160
156
}
161
157
162
158
} // end of namespace variable_declaration_in_condition
163
159
160
+ namespace important_returning_pointer_loaded_from {
161
+ bool coin ();
162
+
163
+ int *getIntPtr ();
164
+
165
+ void storeValue (int **i) {
166
+ *i = getIntPtr (); // tracking-note{{Value assigned to 'i'}}
167
+ }
168
+
169
+ int *conjurePointer () {
170
+ int *i;
171
+ storeValue (&i); // tracking-note{{Calling 'storeValue'}}
172
+ // tracking-note@-1{{Returning from 'storeValue'}}
173
+ return i; // tracking-note{{Returning pointer (loaded from 'i')}}
174
+ }
175
+
176
+ void f (int *ptr) {
177
+ if (ptr) // expected-note{{Assuming 'ptr' is null}}
178
+ // expected-note@-1{{Taking false branch}}
179
+ ;
180
+ if (!conjurePointer ())
181
+ // tracking-note@-1{{Calling 'conjurePointer'}}
182
+ // tracking-note@-2{{Returning from 'conjurePointer'}}
183
+ // debug-note@-3{{Tracking condition '!conjurePointer()'}}
184
+ // expected-note@-4{{Assuming the condition is true}}
185
+ // expected-note@-5{{Taking true branch}}
186
+ *ptr = 5 ; // expected-warning{{Dereference of null pointer}}
187
+ // expected-note@-1{{Dereference of null pointer}}
188
+ }
189
+ } // end of namespace important_returning_pointer_loaded_from
190
+
191
+ namespace unimportant_returning_pointer_loaded_from {
192
+ bool coin ();
193
+
194
+ int *getIntPtr ();
195
+
196
+ int *conjurePointer () {
197
+ int *i = getIntPtr (); // tracking-note{{'i' initialized here}}
198
+ return i; // tracking-note{{Returning pointer (loaded from 'i')}}
199
+ }
200
+
201
+ void f (int *ptr) {
202
+ if (ptr) // expected-note{{Assuming 'ptr' is null}}
203
+ // expected-note@-1{{Taking false branch}}
204
+ ;
205
+ if (!conjurePointer ())
206
+ // tracking-note@-1{{Calling 'conjurePointer'}}
207
+ // tracking-note@-2{{Returning from 'conjurePointer'}}
208
+ // debug-note@-3{{Tracking condition '!conjurePointer()'}}
209
+ // expected-note@-4{{Assuming the condition is true}}
210
+ // expected-note@-5{{Taking true branch}}
211
+ *ptr = 5 ; // expected-warning{{Dereference of null pointer}}
212
+ // expected-note@-1{{Dereference of null pointer}}
213
+ }
214
+ } // end of namespace unimportant_returning_pointer_loaded_from
215
+
216
+ namespace unimportant_returning_pointer_loaded_from_through_cast {
217
+
218
+ void *conjure ();
219
+
220
+ int *cast (void *P) {
221
+ return static_cast <int *>(P);
222
+ }
223
+
224
+ void f () {
225
+ int *x = 0 ; // expected-note{{'x' initialized to a null pointer value}}
226
+
227
+ if (cast (conjure ()))
228
+ // tracking-note@-1{{Passing value via 1st parameter 'P'}}
229
+ // debug-note@-2{{Tracking condition 'cast(conjure())'}}
230
+ // expected-note@-3{{Assuming the condition is false}}
231
+ // expected-note@-4{{Taking false branch}}
232
+ return ;
233
+ *x = 5 ; // expected-warning{{Dereference of null pointer}}
234
+ // expected-note@-1{{Dereference of null pointer}}
235
+ }
236
+
237
+ } // end of namespace unimportant_returning_pointer_loaded_from_through_cast
238
+
164
239
namespace unimportant_returning_value_note {
165
240
bool coin ();
166
241
167
- bool flipCoin () { return coin (); } // tracking-note{{Returning value}}
242
+ bool flipCoin () { return coin (); }
168
243
169
244
void i (int *ptr) {
170
245
if (ptr) // expected-note{{Assuming 'ptr' is null}}
171
246
// expected-note@-1{{Taking false branch}}
172
247
;
173
248
if (!flipCoin ())
174
- // tracking-note@-1{{Calling 'flipCoin'}}
175
- // tracking-note@-2{{Returning from 'flipCoin'}}
176
- // debug-note@-3{{Tracking condition '!flipCoin()'}}
177
- // expected-note@-4{{Assuming the condition is true}}
178
- // expected-note@-5{{Taking true branch}}
249
+ // debug-note@-1{{Tracking condition '!flipCoin()'}}
250
+ // expected-note@-2{{Assuming the condition is true}}
251
+ // expected-note@-3{{Taking true branch}}
179
252
*ptr = 5 ; // expected-warning{{Dereference of null pointer}}
180
253
// expected-note@-1{{Dereference of null pointer}}
181
254
}
@@ -207,6 +280,36 @@ void i(int *ptr) {
207
280
}
208
281
} // end of namespace important_returning_value_note
209
282
283
+ namespace important_returning_value_note_in_linear_function {
284
+ bool coin ();
285
+
286
+ struct super_complicated_template_hackery {
287
+ static constexpr bool value = false ;
288
+ };
289
+
290
+ bool flipCoin () {
291
+ if (super_complicated_template_hackery::value)
292
+ // tracking-note@-1{{'value' is false}}
293
+ // tracking-note@-2{{Taking false branch}}
294
+ return true ;
295
+ return coin (); // tracking-note{{Returning value}}
296
+ }
297
+
298
+ void i (int *ptr) {
299
+ if (ptr) // expected-note{{Assuming 'ptr' is null}}
300
+ // expected-note@-1{{Taking false branch}}
301
+ ;
302
+ if (!flipCoin ())
303
+ // tracking-note@-1{{Calling 'flipCoin'}}
304
+ // tracking-note@-2{{Returning from 'flipCoin'}}
305
+ // debug-note@-3{{Tracking condition '!flipCoin()'}}
306
+ // expected-note@-4{{Assuming the condition is true}}
307
+ // expected-note@-5{{Taking true branch}}
308
+ *ptr = 5 ; // expected-warning{{Dereference of null pointer}}
309
+ // expected-note@-1{{Dereference of null pointer}}
310
+ }
311
+ } // end of namespace important_returning_value_note_in_linear_function
312
+
210
313
namespace tracked_condition_is_only_initialized {
211
314
int getInt ();
212
315
0 commit comments