[AMDGPU][AsmParser][NFC] Get rid of custom default operand handlers.
[llvm-project.git] / clang / test / Analysis / track-control-dependency-conditions.cpp
blobb762992b6a8f0b4cc2fcfea709924cd7f0616289
1 // RUN: %clang_analyze_cc1 %s -std=c++17 \
2 // RUN: -verify=expected,tracking \
3 // RUN: -analyzer-config track-conditions=true \
4 // RUN: -analyzer-output=text \
5 // RUN: -analyzer-checker=core
7 // RUN: not %clang_analyze_cc1 -std=c++17 -verify %s \
8 // RUN: -analyzer-checker=core \
9 // RUN: -analyzer-config track-conditions=false \
10 // RUN: -analyzer-config track-conditions-debug=true \
11 // RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-INVALID-DEBUG
13 // CHECK-INVALID-DEBUG: (frontend): invalid input for analyzer-config option
14 // CHECK-INVALID-DEBUG-SAME: 'track-conditions-debug', that expects
15 // CHECK-INVALID-DEBUG-SAME: 'track-conditions' to also be enabled
17 // RUN: %clang_analyze_cc1 %s -std=c++17 \
18 // RUN: -verify=expected,tracking,debug \
19 // RUN: -analyzer-config track-conditions=true \
20 // RUN: -analyzer-config track-conditions-debug=true \
21 // RUN: -analyzer-output=text \
22 // RUN: -analyzer-checker=core
24 // RUN: %clang_analyze_cc1 %s -std=c++17 -verify \
25 // RUN: -analyzer-output=text \
26 // RUN: -analyzer-config track-conditions=false \
27 // RUN: -analyzer-checker=core
29 namespace example_1 {
30 int flag;
31 bool coin();
33 void foo() {
34 flag = coin(); // tracking-note-re{{{{^}}Value assigned to 'flag', which participates in a condition later{{$}}}}
37 void test() {
38 int *x = 0; // expected-note-re{{{{^}}'x' initialized to a null pointer value{{$}}}}
39 flag = 1;
41 foo(); // TODO: Add nodes here about flag's value being invalidated.
42 if (flag) // expected-note-re {{{{^}}Assuming 'flag' is 0{{$}}}}
43 // expected-note-re@-1{{{{^}}Taking false branch{{$}}}}
44 x = new int;
46 foo(); // tracking-note-re{{{{^}}Calling 'foo'{{$}}}}
47 // tracking-note-re@-1{{{{^}}Returning from 'foo'{{$}}}}
49 if (flag) // expected-note-re {{{{^}}Assuming 'flag' is not equal to 0{{$}}}}
50 // expected-note-re@-1{{{{^}}Taking true branch{{$}}}}
51 // debug-note-re@-2{{{{^}}Tracking condition 'flag'{{$}}}}
53 *x = 5; // expected-warning{{Dereference of null pointer}}
54 // expected-note@-1{{Dereference of null pointer}}
56 } // end of namespace example_1
58 namespace example_2 {
59 int flag;
60 bool coin();
62 void foo() {
63 flag = coin(); // tracking-note-re{{{{^}}Value assigned to 'flag', which participates in a condition later{{$}}}}
66 void test() {
67 int *x = 0;
68 flag = 1;
70 foo();
71 if (flag) // expected-note-re {{{{^}}Assuming 'flag' is 0{{$}}}}
72 // expected-note-re@-1{{{{^}}Taking false branch{{$}}}}
73 x = new int;
75 x = 0; // expected-note-re{{{{^}}Null pointer value stored to 'x'{{$}}}}
77 foo(); // tracking-note-re{{{{^}}Calling 'foo'{{$}}}}
78 // tracking-note-re@-1{{{{^}}Returning from 'foo'{{$}}}}
80 if (flag) // expected-note-re {{{{^}}Assuming 'flag' is not equal to 0{{$}}}}
81 // expected-note-re@-1{{{{^}}Taking true branch{{$}}}}
82 // debug-note-re@-2{{{{^}}Tracking condition 'flag'{{$}}}}
84 *x = 5; // expected-warning{{Dereference of null pointer}}
85 // expected-note@-1{{Dereference of null pointer}}
87 } // end of namespace example_2
89 namespace global_variable_invalidation {
90 int flag;
91 bool coin();
93 void foo() {
94 // coin() could write bar, do it's invalidated.
95 flag = coin(); // tracking-note-re{{{{^}}Value assigned to 'flag', which participates in a condition later{{$}}}}
96 // tracking-note-re@-1{{{{^}}Value assigned to 'bar', which participates in a condition later{{$}}}}
99 int bar;
101 void test() {
102 int *x = 0; // expected-note-re{{{{^}}'x' initialized to a null pointer value{{$}}}}
103 flag = 1;
105 foo(); // tracking-note-re{{{{^}}Calling 'foo'{{$}}}}
106 // tracking-note-re@-1{{{{^}}Returning from 'foo'{{$}}}}
108 if (bar) // expected-note-re {{{{^}}Assuming 'bar' is not equal to 0{{$}}}}
109 // expected-note-re@-1{{{{^}}Taking true branch{{$}}}}
110 // debug-note-re@-2{{{{^}}Tracking condition 'bar'{{$}}}}
111 if (flag) // expected-note-re {{{{^}}Assuming 'flag' is not equal to 0{{$}}}}
112 // expected-note-re@-1{{{{^}}Taking true branch{{$}}}}
113 // debug-note-re@-2{{{{^}}Tracking condition 'flag'{{$}}}}
115 *x = 5; // expected-warning{{Dereference of null pointer}}
116 // expected-note@-1{{Dereference of null pointer}}
118 } // end of namespace global_variable_invalidation
120 namespace variable_declaration_in_condition {
121 bool coin();
123 bool foo() {
124 return coin();
127 int bar;
129 void test() {
130 int *x = 0; // expected-note-re{{{{^}}'x' initialized to a null pointer value{{$}}}}
132 if (int flag = foo()) // debug-note-re{{{{^}}Tracking condition 'flag'{{$}}}}
133 // expected-note-re@-1{{{{^}}Assuming 'flag' is not equal to 0{{$}}}}
134 // expected-note-re@-2{{{{^}}Taking true branch{{$}}}}
136 *x = 5; // expected-warning{{Dereference of null pointer}}
137 // expected-note@-1{{Dereference of null pointer}}
139 } // end of namespace variable_declaration_in_condition
141 namespace conversion_to_bool {
142 bool coin();
144 struct ConvertsToBool {
145 operator bool() const { return coin(); }
148 void test() {
149 int *x = 0; // expected-note-re{{{{^}}'x' initialized to a null pointer value{{$}}}}
151 if (ConvertsToBool())
152 // expected-note-re@-1{{{{^}}Assuming the condition is true{{$}}}}
153 // expected-note-re@-2{{{{^}}Taking true branch{{$}}}}
154 *x = 5; // expected-warning{{Dereference of null pointer}}
155 // expected-note@-1{{Dereference of null pointer}}
158 } // namespace conversion_to_bool
160 namespace note_from_different_but_not_nested_stackframe {
162 void nullptrDeref(int *ptr, bool True) {
163 if (True) // expected-note-re{{{{^}}'True' is true{{$}}}}
164 // expected-note-re@-1{{{{^}}Taking true branch{{$}}}}
165 // debug-note-re@-2{{{{^}}Tracking condition 'True'{{$}}}}
166 *ptr = 5;
167 // expected-note@-1{{Dereference of null pointer (loaded from variable 'ptr')}}
168 // expected-warning@-2{{Dereference of null pointer (loaded from variable 'ptr')}}
171 void f() {
172 int *ptr = nullptr;
173 // expected-note-re@-1{{{{^}}'ptr' initialized to a null pointer value{{$}}}}
174 bool True = true;
175 nullptrDeref(ptr, True);
176 // expected-note-re@-1{{{{^}}Passing null pointer value via 1st parameter 'ptr'{{$}}}}
177 // expected-note-re@-2{{{{^}}Calling 'nullptrDeref'{{$}}}}
180 } // end of namespace note_from_different_but_not_nested_stackframe
182 namespace important_returning_pointer_loaded_from {
183 bool coin();
185 int *getIntPtr();
187 void storeValue(int **i) {
188 *i = getIntPtr();
191 int *conjurePointer() {
192 int *i;
193 storeValue(&i);
194 return i;
197 void f(int *ptr) {
198 if (ptr) // expected-note-re{{{{^}}Assuming 'ptr' is null{{$}}}}
199 // expected-note-re@-1{{{{^}}Taking false branch{{$}}}}
201 if (!conjurePointer())
202 // expected-note-re@-1{{{{^}}Assuming the condition is true{{$}}}}
203 // expected-note-re@-2{{{{^}}Taking true branch{{$}}}}
204 *ptr = 5; // expected-warning{{Dereference of null pointer}}
205 // expected-note@-1{{Dereference of null pointer}}
207 } // end of namespace important_returning_pointer_loaded_from
209 namespace unimportant_returning_pointer_loaded_from {
210 bool coin();
212 int *getIntPtr();
214 int *conjurePointer() {
215 int *i = getIntPtr();
216 return i;
219 void f(int *ptr) {
220 if (ptr) // expected-note-re{{{{^}}Assuming 'ptr' is null{{$}}}}
221 // expected-note-re@-1{{{{^}}Taking false branch{{$}}}}
223 if (!conjurePointer())
224 // expected-note-re@-1{{{{^}}Assuming the condition is true{{$}}}}
225 // expected-note-re@-2{{{{^}}Taking true branch{{$}}}}
226 *ptr = 5; // expected-warning{{Dereference of null pointer}}
227 // expected-note@-1{{Dereference of null pointer}}
229 } // end of namespace unimportant_returning_pointer_loaded_from
231 namespace unimportant_returning_pointer_loaded_from_through_cast {
233 void *conjure();
235 int *cast(void *P) {
236 return static_cast<int *>(P);
239 void f() {
240 int *x = 0; // expected-note-re{{{{^}}'x' initialized to a null pointer value{{$}}}}
242 if (cast(conjure()))
243 // expected-note-re@-1{{{{^}}Assuming the condition is false{{$}}}}
244 // expected-note-re@-2{{{{^}}Taking false branch{{$}}}}
245 return;
246 *x = 5; // expected-warning{{Dereference of null pointer}}
247 // expected-note@-1{{Dereference of null pointer}}
250 } // end of namespace unimportant_returning_pointer_loaded_from_through_cast
252 namespace unimportant_returning_value_note {
253 bool coin();
255 bool flipCoin() { return coin(); }
257 void i(int *ptr) {
258 if (ptr) // expected-note-re{{{{^}}Assuming 'ptr' is null{{$}}}}
259 // expected-note-re@-1{{{{^}}Taking false branch{{$}}}}
261 if (!flipCoin())
262 // expected-note-re@-1{{{{^}}Assuming the condition is true{{$}}}}
263 // expected-note-re@-2{{{{^}}Taking true branch{{$}}}}
264 *ptr = 5; // expected-warning{{Dereference of null pointer}}
265 // expected-note@-1{{Dereference of null pointer}}
267 } // end of namespace unimportant_returning_value_note
269 namespace important_returning_value_note {
270 bool coin();
272 bool flipCoin() {
273 if (coin())
274 return true;
275 return coin();
278 void i(int *ptr) {
279 if (ptr) // expected-note-re{{{{^}}Assuming 'ptr' is null{{$}}}}
280 // expected-note-re@-1{{{{^}}Taking false branch{{$}}}}
282 if (!flipCoin())
283 // expected-note-re@-1{{{{^}}Assuming the condition is true{{$}}}}
284 // expected-note-re@-2{{{{^}}Taking true branch{{$}}}}
285 *ptr = 5; // expected-warning{{Dereference of null pointer}}
286 // expected-note@-1{{Dereference of null pointer}}
288 } // end of namespace important_returning_value_note
290 namespace important_returning_value_note_in_linear_function {
291 bool coin();
292 int flag;
294 struct super_complicated_template_hackery {
295 static constexpr bool value = false;
298 void flipCoin() {
299 if (super_complicated_template_hackery::value)
300 // tracking-note-re@-1{{{{^}}'value' is false{{$}}}}
301 // tracking-note-re@-2{{{{^}}Taking false branch{{$}}}}
302 return;
303 flag = false; // tracking-note-re{{{{^}}The value 0 is assigned to 'flag', which participates in a condition later{{$}}}}
306 void i(int *ptr) {
307 flag = true;
308 if (ptr) // expected-note-re{{{{^}}Assuming 'ptr' is null{{$}}}}
309 // expected-note-re@-1{{{{^}}Taking false branch{{$}}}}
311 flipCoin();
312 // tracking-note-re@-1{{{{^}}Calling 'flipCoin'{{$}}}}
313 // tracking-note-re@-2{{{{^}}Returning from 'flipCoin'{{$}}}}
314 if (!flag)
315 // debug-note-re@-1{{{{^}}Tracking condition '!flag'{{$}}}}
316 // expected-note-re@-2{{{{^}}'flag' is 0{{$}}}}
317 // expected-note-re@-3{{{{^}}Taking true branch{{$}}}}
318 *ptr = 5; // expected-warning{{Dereference of null pointer}}
319 // expected-note@-1{{Dereference of null pointer}}
321 } // end of namespace important_returning_value_note_in_linear_function
323 namespace tracked_condition_is_only_initialized {
324 int getInt();
326 void f() {
327 int flag = getInt();
328 int *x = 0; // expected-note-re{{{{^}}'x' initialized to a null pointer value{{$}}}}
329 if (flag) // expected-note-re{{{{^}}Assuming 'flag' is not equal to 0{{$}}}}
330 // expected-note-re@-1{{{{^}}Taking true branch{{$}}}}
331 // debug-note-re@-2{{{{^}}Tracking condition 'flag'{{$}}}}
332 *x = 5; // expected-warning{{Dereference of null pointer}}
333 // expected-note@-1{{Dereference of null pointer}}
335 } // end of namespace tracked_condition_is_only_initialized
337 namespace tracked_condition_written_in_same_stackframe {
338 int flag;
339 int getInt();
341 void f(int y) {
342 y = 1;
343 flag = y;
345 int *x = 0; // expected-note-re{{{{^}}'x' initialized to a null pointer value{{$}}}}
346 if (flag) // expected-note-re{{{{^}}'flag' is 1{{$}}}}
347 // expected-note-re@-1{{{{^}}Taking true branch{{$}}}}
348 // debug-note-re@-2{{{{^}}Tracking condition 'flag'{{$}}}}
349 *x = 5; // expected-warning{{Dereference of null pointer}}
350 // expected-note@-1{{Dereference of null pointer}}
352 } // end of namespace tracked_condition_written_in_same_stackframe
354 namespace tracked_condition_written_in_nested_stackframe {
355 int flag;
356 int getInt();
358 void foo() {
359 int y;
360 y = 1;
361 flag = y; // tracking-note-re{{{{^}}The value 1 is assigned to 'flag', which participates in a condition later{{$}}}}
364 void f(int y) {
365 int *x = 0; // expected-note-re{{{{^}}'x' initialized to a null pointer value{{$}}}}
367 foo(); // tracking-note-re{{{{^}}Calling 'foo'{{$}}}}
368 // tracking-note-re@-1{{{{^}}Returning from 'foo'{{$}}}}
370 if (flag) // expected-note-re{{{{^}}'flag' is 1{{$}}}}
371 // expected-note-re@-1{{{{^}}Taking true branch{{$}}}}
372 // debug-note-re@-2{{{{^}}Tracking condition 'flag'{{$}}}}
373 *x = 5; // expected-warning{{Dereference of null pointer}}
374 // expected-note@-1{{Dereference of null pointer}}
376 } // end of namespace tracked_condition_written_in_nested_stackframe
378 namespace condition_written_in_nested_stackframe_before_assignment {
379 int flag = 0;
380 int getInt();
382 void foo() {
383 flag = getInt(); // tracking-note-re{{{{^}}Value assigned to 'flag', which participates in a condition later{{$}}}}
386 void f() {
387 int *x = 0; // expected-note-re{{{{^}}'x' initialized to a null pointer value{{$}}}}
388 int y = 0;
390 foo(); // tracking-note-re{{{{^}}Calling 'foo'{{$}}}}
391 // tracking-note-re@-1{{{{^}}Returning from 'foo'{{$}}}}
392 y = flag;
394 if (y) // expected-note-re{{{{^}}Assuming 'y' is not equal to 0{{$}}}}
395 // expected-note-re@-1{{{{^}}Taking true branch{{$}}}}
396 // debug-note-re@-2{{{{^}}Tracking condition 'y'{{$}}}}
397 *x = 5; // expected-warning{{Dereference of null pointer}}
398 // expected-note@-1{{Dereference of null pointer}}
400 } // end of namespace condition_written_in_nested_stackframe_before_assignment
402 namespace dont_explain_foreach_loops {
404 struct Iterator {
405 int *pos;
406 bool operator!=(Iterator other) const {
407 return pos && other.pos && pos != other.pos;
409 int operator*();
410 Iterator operator++();
413 struct Container {
414 Iterator begin();
415 Iterator end();
418 void f(Container Cont) {
419 int flag = 0;
420 int *x = 0; // expected-note-re{{{{^}}'x' initialized to a null pointer value{{$}}}}
421 for (int i : Cont)
422 if (i) // expected-note-re {{{{^}}Assuming 'i' is not equal to 0{{$}}}}
423 // expected-note-re@-1{{{{^}}Taking true branch{{$}}}}
424 // debug-note-re@-2{{{{^}}Tracking condition 'i'{{$}}}}
425 flag = i;
427 if (flag) // expected-note-re{{{{^}}'flag' is not equal to 0{{$}}}}
428 // expected-note-re@-1{{{{^}}Taking true branch{{$}}}}
429 // debug-note-re@-2{{{{^}}Tracking condition 'flag'{{$}}}}
430 *x = 5; // expected-warning{{Dereference of null pointer}}
431 // expected-note@-1{{Dereference of null pointer}}
433 } // end of namespace dont_explain_foreach_loops
435 namespace condition_lambda_capture_by_reference_last_write {
436 int getInt();
438 [[noreturn]] void halt();
440 void f(int flag) {
441 int *x = 0; // expected-note-re{{{{^}}'x' initialized to a null pointer value{{$}}}}
443 auto lambda = [&flag]() {
444 flag = getInt(); // tracking-note-re{{{{^}}Value assigned to 'flag', which participates in a condition later{{$}}}}
447 lambda(); // tracking-note-re{{{{^}}Calling 'operator()'{{$}}}}
448 // tracking-note-re@-1{{{{^}}Returning from 'operator()'{{$}}}}
450 if (flag) // expected-note-re{{{{^}}Assuming 'flag' is not equal to 0{{$}}}}
451 // expected-note-re@-1{{{{^}}Taking true branch{{$}}}}
452 // debug-note-re@-2{{{{^}}Tracking condition 'flag'{{$}}}}
453 *x = 5; // expected-warning{{Dereference of null pointer}}
454 // expected-note@-1{{Dereference of null pointer}}
456 } // end of namespace condition_lambda_capture_by_reference_last_write
458 namespace condition_lambda_capture_by_value_assumption {
459 int getInt();
461 [[noreturn]] void halt();
463 void bar(int &flag) {
464 flag = getInt(); // tracking-note-re{{{{^}}Value assigned to 'flag', which participates in a condition later{{$}}}}
467 void f(int flag) {
468 int *x = 0; // expected-note-re{{{{^}}'x' initialized to a null pointer value{{$}}}}
470 auto lambda = [flag]() {
471 if (!flag) // tracking-note-re{{{{^}}Assuming 'flag' is not equal to 0, which participates in a condition later{{$}}}}
472 // tracking-note-re@-1{{{{^}}Taking false branch{{$}}}}
473 halt();
476 bar(flag); // tracking-note-re{{{{^}}Calling 'bar'{{$}}}}
477 // tracking-note-re@-1{{{{^}}Returning from 'bar'{{$}}}}
478 lambda(); // tracking-note-re{{{{^}}Calling 'operator()'{{$}}}}
479 // tracking-note-re@-1{{{{^}}Returning from 'operator()'{{$}}}}
481 if (flag) // expected-note-re{{{{^}}Assuming 'flag' is not equal to 0{{$}}}}
482 // expected-note-re@-1{{{{^}}Taking true branch{{$}}}}
483 // debug-note-re@-2{{{{^}}Tracking condition 'flag'{{$}}}}
484 *x = 5; // expected-warning{{Dereference of null pointer}}
485 // expected-note@-1{{Dereference of null pointer}}
487 } // end of namespace condition_lambda_capture_by_value_assumption
489 namespace condition_lambda_capture_by_reference_assumption {
490 int getInt();
492 [[noreturn]] void halt();
494 void bar(int &flag) {
495 flag = getInt(); // tracking-note-re{{{{^}}Value assigned to 'flag', which participates in a condition later{{$}}}}
498 void f(int flag) {
499 int *x = 0; // expected-note-re{{{{^}}'x' initialized to a null pointer value{{$}}}}
501 auto lambda = [&flag]() {
502 if (!flag) // tracking-note-re{{{{^}}Assuming 'flag' is not equal to 0, which participates in a condition later{{$}}}}
503 // tracking-note-re@-1{{{{^}}Taking false branch{{$}}}}
504 halt();
507 bar(flag); // tracking-note-re{{{{^}}Calling 'bar'{{$}}}}
508 // tracking-note-re@-1{{{{^}}Returning from 'bar'{{$}}}}
509 lambda(); // tracking-note-re{{{{^}}Calling 'operator()'{{$}}}}
510 // tracking-note-re@-1{{{{^}}Returning from 'operator()'{{$}}}}
512 if (flag) // expected-note-re{{{{^}}'flag' is not equal to 0{{$}}}}
513 // expected-note-re@-1{{{{^}}Taking true branch{{$}}}}
514 // debug-note-re@-2{{{{^}}Tracking condition 'flag'{{$}}}}
515 *x = 5; // expected-warning{{Dereference of null pointer}}
516 // expected-note@-1{{Dereference of null pointer}}
518 } // end of namespace condition_lambda_capture_by_reference_assumption
520 namespace collapse_point_not_in_condition_bool {
522 [[noreturn]] void halt();
524 void check(bool b) {
525 if (!b) // tracking-note-re{{{{^}}Assuming 'b' is true, which participates in a condition later{{$}}}}
526 // tracking-note-re@-1{{{{^}}Taking false branch{{$}}}}
527 halt();
530 void f(bool flag) {
531 int *x = 0; // expected-note-re{{{{^}}'x' initialized to a null pointer value{{$}}}}
533 check(flag); // tracking-note-re{{{{^}}Calling 'check'{{$}}}}
534 // tracking-note-re@-1{{{{^}}Returning from 'check'{{$}}}}
536 if (flag) // expected-note-re{{{{^}}'flag' is true{{$}}}}
537 // expected-note-re@-1{{{{^}}Taking true branch{{$}}}}
538 // debug-note-re@-2{{{{^}}Tracking condition 'flag'{{$}}}}
539 *x = 5; // expected-warning{{Dereference of null pointer}}
540 // expected-note@-1{{Dereference of null pointer}}
542 } // end of namespace collapse_point_not_in_condition_bool
544 namespace collapse_point_not_in_condition {
546 [[noreturn]] void halt();
548 void assert(int b) {
549 if (!b) // tracking-note-re{{{{^}}Assuming 'b' is not equal to 0, which participates in a condition later{{$}}}}
550 // tracking-note-re@-1{{{{^}}Taking false branch{{$}}}}
551 halt();
554 void f(int flag) {
555 int *x = 0; // expected-note-re{{{{^}}'x' initialized to a null pointer value{{$}}}}
557 assert(flag); // tracking-note-re{{{{^}}Calling 'assert'{{$}}}}
558 // tracking-note-re@-1{{{{^}}Returning from 'assert'{{$}}}}
560 if (flag) // expected-note-re{{{{^}}'flag' is not equal to 0{{$}}}}
561 // expected-note-re@-1{{{{^}}Taking true branch{{$}}}}
562 // debug-note-re@-2{{{{^}}Tracking condition 'flag'{{$}}}}
563 *x = 5; // expected-warning{{Dereference of null pointer}}
564 // expected-note@-1{{Dereference of null pointer}}
567 } // end of namespace collapse_point_not_in_condition
569 namespace unimportant_write_before_collapse_point {
571 [[noreturn]] void halt();
573 void assert(int b) {
574 if (!b) // tracking-note-re{{{{^}}Assuming 'b' is not equal to 0, which participates in a condition later{{$}}}}
575 // tracking-note-re@-1{{{{^}}Taking false branch{{$}}}}
576 halt();
578 int getInt();
580 void f(int flag) {
581 int *x = 0; // expected-note-re{{{{^}}'x' initialized to a null pointer value{{$}}}}
583 flag = getInt();
584 assert(flag); // tracking-note-re{{{{^}}Calling 'assert'{{$}}}}
585 // tracking-note-re@-1{{{{^}}Returning from 'assert'{{$}}}}
587 if (flag) // expected-note-re{{{{^}}'flag' is not equal to 0{{$}}}}
588 // expected-note-re@-1{{{{^}}Taking true branch{{$}}}}
589 // debug-note-re@-2{{{{^}}Tracking condition 'flag'{{$}}}}
590 *x = 5; // expected-warning{{Dereference of null pointer}}
591 // expected-note@-1{{Dereference of null pointer}}
594 } // end of namespace unimportant_write_before_collapse_point
596 namespace dont_crash_on_nonlogical_binary_operator {
598 void f6(int x) {
599 int a[20];
600 if (x == 25) {} // expected-note{{Assuming 'x' is equal to 25}}
601 // expected-note@-1{{Taking true branch}}
602 if (a[x] == 123) {} // expected-warning{{The left operand of '==' is a garbage value due to array index out of bounds}}
603 // expected-note@-1{{The left operand of '==' is a garbage value due to array index out of bounds}}
606 } // end of namespace dont_crash_on_nonlogical_binary_operator
608 namespace collapse_point_not_in_condition_binary_op {
610 [[noreturn]] void halt();
612 void check(int b) {
613 if (b == 1) // tracking-note-re{{{{^}}Assuming 'b' is not equal to 1, which participates in a condition later{{$}}}}
614 // tracking-note-re@-1{{{{^}}Taking false branch{{$}}}}
615 halt();
618 void f(int flag) {
619 int *x = 0; // expected-note-re{{{{^}}'x' initialized to a null pointer value{{$}}}}
621 check(flag); // tracking-note-re{{{{^}}Calling 'check'{{$}}}}
622 // tracking-note-re@-1{{{{^}}Returning from 'check'{{$}}}}
624 if (flag) // expected-note-re{{{{^}}Assuming 'flag' is not equal to 0{{$}}}}
625 // expected-note-re@-1{{{{^}}Taking true branch{{$}}}}
626 // debug-note-re@-2{{{{^}}Tracking condition 'flag'{{$}}}}
627 *x = 5; // expected-warning{{Dereference of null pointer}}
628 // expected-note@-1{{Dereference of null pointer}}
631 } // end of namespace collapse_point_not_in_condition_binary_op
633 namespace collapse_point_not_in_condition_as_field {
635 [[noreturn]] void halt();
636 struct IntWrapper {
637 int b;
638 IntWrapper();
640 void check() {
641 if (!b) // tracking-note-re{{{{^}}Assuming field 'b' is not equal to 0, which participates in a condition later{{$}}}}
642 // tracking-note-re@-1{{{{^}}Taking false branch{{$}}}}
643 halt();
644 return;
648 void f(IntWrapper i) {
649 int *x = 0; // expected-note-re{{{{^}}'x' initialized to a null pointer value{{$}}}}
651 i.check(); // tracking-note-re{{{{^}}Calling 'IntWrapper::check'{{$}}}}
652 // tracking-note-re@-1{{{{^}}Returning from 'IntWrapper::check'{{$}}}}
653 if (i.b) // expected-note-re{{{{^}}Field 'b' is not equal to 0{{$}}}}
654 // expected-note-re@-1{{{{^}}Taking true branch{{$}}}}
655 // debug-note-re@-2{{{{^}}Tracking condition 'i.b'{{$}}}}
656 *x = 5; // expected-warning{{Dereference of null pointer}}
657 // expected-note@-1{{Dereference of null pointer}}
660 } // end of namespace collapse_point_not_in_condition_as_field
662 namespace assignemnt_in_condition_in_nested_stackframe {
663 int flag;
665 bool coin();
667 [[noreturn]] void halt();
669 void foo() {
670 if ((flag = coin()))
671 // tracking-note-re@-1{{{{^}}Value assigned to 'flag', which participates in a condition later{{$}}}}
672 // tracking-note-re@-2{{{{^}}Assuming 'flag' is not equal to 0, which participates in a condition later{{$}}}}
673 // tracking-note-re@-3{{{{^}}Taking true branch{{$}}}}
674 return;
675 halt();
676 return;
679 void f() {
680 int *x = 0; // expected-note-re{{{{^}}'x' initialized to a null pointer value{{$}}}}
682 foo(); // tracking-note-re{{{{^}}Calling 'foo'{{$}}}}
683 // tracking-note-re@-1{{{{^}}Returning from 'foo'{{$}}}}
684 if (flag) // expected-note-re{{{{^}}'flag' is not equal to 0{{$}}}}
685 // expected-note-re@-1{{{{^}}Taking true branch{{$}}}}
686 // debug-note-re@-2{{{{^}}Tracking condition 'flag'{{$}}}}
687 *x = 5; // expected-warning{{Dereference of null pointer}}
688 // expected-note@-1{{Dereference of null pointer}}
690 } // end of namespace assignemnt_in_condition_in_nested_stackframe
692 namespace condition_variable_less {
693 int flag;
695 bool coin();
697 [[noreturn]] void halt();
699 void foo() {
700 if (flag > 0)
701 // tracking-note-re@-1{{{{^}}Assuming 'flag' is > 0, which participates in a condition later{{$}}}}
702 // tracking-note-re@-2{{{{^}}Taking true branch{{$}}}}
703 return;
704 halt();
705 return;
708 void f() {
709 int *x = 0; // expected-note-re{{{{^}}'x' initialized to a null pointer value{{$}}}}
711 foo(); // tracking-note-re{{{{^}}Calling 'foo'{{$}}}}
712 // tracking-note-re@-1{{{{^}}Returning from 'foo'{{$}}}}
713 if (flag) // expected-note-re{{{{^}}'flag' is not equal to 0{{$}}}}
714 // expected-note-re@-1{{{{^}}Taking true branch{{$}}}}
715 // debug-note-re@-2{{{{^}}Tracking condition 'flag'{{$}}}}
716 *x = 5; // expected-warning{{Dereference of null pointer}}
717 // expected-note@-1{{Dereference of null pointer}}
719 } // end of namespace condition_variable_less
721 namespace dont_track_assertlike_conditions {
723 extern void __assert_fail(__const char *__assertion, __const char *__file,
724 unsigned int __line, __const char *__function)
725 __attribute__((__noreturn__));
726 #define assert(expr) \
727 ((expr) ? (void)(0) : __assert_fail(#expr, __FILE__, __LINE__, __func__))
729 int getInt();
731 int cond1;
733 void bar() {
734 cond1 = getInt();
737 void f(int flag) {
738 int *x = 0; // expected-note-re{{{{^}}'x' initialized to a null pointer value{{$}}}}
740 flag = getInt();
742 bar();
743 assert(cond1); // expected-note-re{{{{^}}Assuming 'cond1' is not equal to 0{{$}}}}
744 // expected-note-re@-1{{{{^}}'?' condition is true{{$}}}}
746 if (flag) // expected-note-re{{{{^}}Assuming 'flag' is not equal to 0{{$}}}}
747 // expected-note-re@-1{{{{^}}Taking true branch{{$}}}}
748 // debug-note-re@-2{{{{^}}Tracking condition 'flag'{{$}}}}
749 *x = 5; // expected-warning{{Dereference of null pointer}}
750 // expected-note@-1{{Dereference of null pointer}}
753 #undef assert
754 } // end of namespace dont_track_assertlike_conditions
756 namespace dont_track_assertlike_and_conditions {
758 extern void __assert_fail(__const char *__assertion, __const char *__file,
759 unsigned int __line, __const char *__function)
760 __attribute__((__noreturn__));
761 #define assert(expr) \
762 ((expr) ? (void)(0) : __assert_fail(#expr, __FILE__, __LINE__, __func__))
764 int getInt();
766 int cond1;
767 int cond2;
769 void bar() {
770 cond1 = getInt();
771 cond2 = getInt();
774 void f(int flag) {
775 int *x = 0; // expected-note-re{{{{^}}'x' initialized to a null pointer value{{$}}}}
777 flag = getInt();
779 bar();
780 assert(cond1 && cond2);
781 // expected-note-re@-1{{{{^}}Assuming 'cond1' is not equal to 0{{$}}}}
782 // expected-note-re@-2{{{{^}}Assuming 'cond2' is not equal to 0{{$}}}}
783 // expected-note-re@-3{{{{^}}'?' condition is true{{$}}}}
784 // expected-note-re@-4{{{{^}}Left side of '&&' is true{{$}}}}
786 if (flag) // expected-note-re{{{{^}}Assuming 'flag' is not equal to 0{{$}}}}
787 // expected-note-re@-1{{{{^}}Taking true branch{{$}}}}
788 // debug-note-re@-2{{{{^}}Tracking condition 'flag'{{$}}}}
789 *x = 5; // expected-warning{{Dereference of null pointer}}
790 // expected-note@-1{{Dereference of null pointer}}
793 #undef assert
794 } // end of namespace dont_track_assertlike_and_conditions
796 namespace dont_track_assertlike_or_conditions {
798 extern void __assert_fail(__const char *__assertion, __const char *__file,
799 unsigned int __line, __const char *__function)
800 __attribute__((__noreturn__));
801 #define assert(expr) \
802 ((expr) ? (void)(0) : __assert_fail(#expr, __FILE__, __LINE__, __func__))
804 int getInt();
806 int cond1;
807 int cond2;
809 void bar() {
810 cond1 = getInt();
811 cond2 = getInt();
814 void f(int flag) {
815 int *x = 0; // expected-note-re{{{{^}}'x' initialized to a null pointer value{{$}}}}
817 flag = getInt();
819 bar();
820 assert(cond1 || cond2);
821 // expected-note-re@-1{{{{^}}Assuming 'cond1' is not equal to 0{{$}}}}
822 // expected-note-re@-2{{{{^}}Left side of '||' is true{{$}}}}
824 if (flag) // expected-note-re{{{{^}}Assuming 'flag' is not equal to 0{{$}}}}
825 // expected-note-re@-1{{{{^}}Taking true branch{{$}}}}
826 // debug-note-re@-2{{{{^}}Tracking condition 'flag'{{$}}}}
827 *x = 5; // expected-warning{{Dereference of null pointer}}
828 // expected-note@-1{{Dereference of null pointer}}
831 #undef assert
832 } // end of namespace dont_track_assertlike_or_conditions
834 namespace dont_track_assert2like_conditions {
836 extern void __assert_fail(__const char *__assertion, __const char *__file,
837 unsigned int __line, __const char *__function)
838 __attribute__((__noreturn__));
839 #define assert(expr) \
840 do { \
841 if (!(expr)) \
842 __assert_fail(#expr, __FILE__, __LINE__, __func__); \
843 } while (0)
845 int getInt();
847 int cond1;
849 void bar() {
850 cond1 = getInt();
853 void f(int flag) {
854 int *x = 0; // expected-note-re{{{{^}}'x' initialized to a null pointer value{{$}}}}
856 flag = getInt();
858 bar();
859 assert(cond1); // expected-note-re{{{{^}}Assuming 'cond1' is not equal to 0{{$}}}}
860 // expected-note-re@-1{{{{^}}Taking false branch{{$}}}}
861 // expected-note-re@-2{{{{^}}Loop condition is false. Exiting loop{{$}}}}
863 if (flag) // expected-note-re{{{{^}}Assuming 'flag' is not equal to 0{{$}}}}
864 // expected-note-re@-1{{{{^}}Taking true branch{{$}}}}
865 // debug-note-re@-2{{{{^}}Tracking condition 'flag'{{$}}}}
866 *x = 5; // expected-warning{{Dereference of null pointer}}
867 // expected-note@-1{{Dereference of null pointer}}
870 #undef assert
871 } // end of namespace dont_track_assert2like_conditions
873 namespace dont_track_assert2like_and_conditions {
875 extern void __assert_fail(__const char *__assertion, __const char *__file,
876 unsigned int __line, __const char *__function)
877 __attribute__((__noreturn__));
878 #define assert(expr) \
879 do { \
880 if (!(expr)) \
881 __assert_fail(#expr, __FILE__, __LINE__, __func__); \
882 } while (0)
884 int getInt();
886 int cond1;
887 int cond2;
889 void bar() {
890 cond1 = getInt();
891 cond2 = getInt();
894 void f(int flag) {
895 int *x = 0; // expected-note-re{{{{^}}'x' initialized to a null pointer value{{$}}}}
897 flag = getInt();
899 bar();
900 assert(cond1 && cond2);
901 // expected-note-re@-1{{{{^}}Assuming 'cond1' is not equal to 0{{$}}}}
902 // expected-note-re@-2{{{{^}}Left side of '&&' is true{{$}}}}
903 // expected-note-re@-3{{{{^}}Assuming the condition is false{{$}}}}
904 // expected-note-re@-4{{{{^}}Taking false branch{{$}}}}
905 // expected-note-re@-5{{{{^}}Loop condition is false. Exiting loop{{$}}}}
907 if (flag) // expected-note-re{{{{^}}Assuming 'flag' is not equal to 0{{$}}}}
908 // expected-note-re@-1{{{{^}}Taking true branch{{$}}}}
909 // debug-note-re@-2{{{{^}}Tracking condition 'flag'{{$}}}}
910 *x = 5; // expected-warning{{Dereference of null pointer}}
911 // expected-note@-1{{Dereference of null pointer}}
914 #undef assert
915 } // end of namespace dont_track_assert2like_and_conditions
917 namespace dont_track_assert2like_or_conditions {
919 extern void __assert_fail(__const char *__assertion, __const char *__file,
920 unsigned int __line, __const char *__function)
921 __attribute__((__noreturn__));
922 #define assert(expr) \
923 do { \
924 if (!(expr)) \
925 __assert_fail(#expr, __FILE__, __LINE__, __func__); \
926 } while (0)
928 int getInt();
930 int cond1;
931 int cond2;
933 void bar() {
934 cond1 = getInt();
935 cond2 = getInt();
938 void f(int flag) {
939 int *x = 0; // expected-note-re{{{{^}}'x' initialized to a null pointer value{{$}}}}
941 flag = getInt();
943 bar();
944 assert(cond1 || cond2);
945 // expected-note-re@-1{{{{^}}Assuming 'cond1' is not equal to 0{{$}}}}
946 // expected-note-re@-2{{{{^}}Left side of '||' is true{{$}}}}
947 // expected-note-re@-3{{{{^}}Taking false branch{{$}}}}
948 // expected-note-re@-4{{{{^}}Loop condition is false. Exiting loop{{$}}}}
950 if (flag) // expected-note-re{{{{^}}Assuming 'flag' is not equal to 0{{$}}}}
951 // expected-note-re@-1{{{{^}}Taking true branch{{$}}}}
952 // debug-note-re@-2{{{{^}}Tracking condition 'flag'{{$}}}}
953 *x = 5; // expected-warning{{Dereference of null pointer}}
954 // expected-note@-1{{Dereference of null pointer}}
957 #undef assert
958 } // end of namespace dont_track_assert2like_or_conditions
960 namespace only_track_the_evaluated_condition {
962 bool coin();
964 void bar(int &flag) {
965 flag = coin(); // tracking-note-re{{{{^}}Value assigned to 'flag', which participates in a condition later{{$}}}}
968 void bar2(int &flag2) {
969 flag2 = coin();
972 void f(int *x) {
973 if (x) // expected-note-re{{{{^}}Assuming 'x' is null{{$}}}}
974 // debug-note-re@-1{{{{^}}Tracking condition 'x'{{$}}}}
975 // expected-note-re@-2{{{{^}}Taking false branch{{$}}}}
976 return;
978 int flag, flag2;
979 bar(flag); // tracking-note-re{{{{^}}Calling 'bar'{{$}}}}
980 // tracking-note-re@-1{{{{^}}Returning from 'bar'{{$}}}}
981 bar2(flag2);
983 if (flag && flag2) // expected-note-re {{{{^}}Assuming 'flag' is 0{{$}}}}
984 // expected-note-re@-1{{{{^}}Left side of '&&' is false{{$}}}}
985 // debug-note-re@-2{{{{^}}Tracking condition 'flag'{{$}}}}
986 return;
988 *x = 5; // expected-warning{{Dereference of null pointer}}
989 // expected-note@-1{{Dereference of null pointer}}
992 } // end of namespace only_track_the_evaluated_condition
994 namespace operator_call_in_condition_point {
996 struct Error {
997 explicit operator bool() {
998 return true;
1002 Error couldFail();
1004 void f(int *x) {
1005 x = nullptr; // expected-note {{Null pointer value stored to 'x'}}
1006 if (auto e = couldFail()) // expected-note {{Taking true branch}}
1007 *x = 5; // expected-warning {{Dereference of null pointer (loaded from variable 'x') [core.NullDereference]}}
1008 // expected-note@-1 {{Dereference}}
1011 } // namespace operator_call_in_condition_point
1013 namespace cxx17_ifinit__operator_call_in_condition_point {
1015 struct Error {
1016 explicit operator bool() {
1017 return true;
1021 Error couldFail();
1023 void f(int *x) {
1024 x = nullptr; // expected-note {{Null pointer value stored to 'x'}}
1025 if (auto e = couldFail(); e) // expected-note {{Taking true branch}}
1026 *x = 5; // expected-warning {{Dereference of null pointer (loaded from variable 'x') [core.NullDereference]}}
1027 // expected-note@-1 {{Dereference}}
1030 } // namespace cxx17_ifinit__operator_call_in_condition_point
1032 namespace funcion_call_in_condition_point {
1034 int alwaysTrue() {
1035 return true;
1038 void f(int *x) {
1039 x = nullptr; // expected-note {{Null pointer value stored to 'x'}}
1040 if (alwaysTrue()) // expected-note {{Taking true branch}}
1041 *x = 5; // expected-warning {{Dereference of null pointer (loaded from variable 'x') [core.NullDereference]}}
1042 // expected-note@-1 {{Dereference}}
1045 } // namespace funcion_call_in_condition_point
1047 namespace funcion_call_negated_in_condition_point {
1049 int alwaysFalse() {
1050 return false;
1053 void f(int *x) {
1054 x = nullptr; // expected-note {{Null pointer value stored to 'x'}}
1055 if (!alwaysFalse()) // expected-note {{Taking true branch}}
1056 *x = 5; // expected-warning {{Dereference of null pointer (loaded from variable 'x') [core.NullDereference]}}
1057 // expected-note@-1 {{Dereference}}
1060 } // namespace funcion_call_negated_in_condition_point
1062 namespace funcion_call_part_of_logical_expr_in_condition_point {
1064 int alwaysFalse() {
1065 return false;
1068 void f(int *x) {
1069 x = nullptr; // expected-note {{Null pointer value stored to 'x'}}
1070 if (!alwaysFalse() && true) // expected-note {{Taking true branch}}
1071 // expected-note@-1 {{Left side of '&&' is true}}
1072 *x = 5; // expected-warning {{Dereference of null pointer (loaded from variable 'x') [core.NullDereference]}}
1073 // expected-note@-1 {{Dereference}}
1076 } // namespace funcion_call_part_of_logical_expr_in_condition_point