xref: /llvm-project/clang/test/Analysis/CheckThatArraySubsciptNodeIsNotCollected.cpp (revision a88025672f89374bfa584e2179a557f44d86da11)
1*a8802567SValeriy Savchenko // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -verify %s
2*a8802567SValeriy Savchenko 
3*a8802567SValeriy Savchenko class A {
4*a8802567SValeriy Savchenko public:
5*a8802567SValeriy Savchenko   int method();
6*a8802567SValeriy Savchenko };
7*a8802567SValeriy Savchenko 
8*a8802567SValeriy Savchenko A *foo();
9*a8802567SValeriy Savchenko void bar(A *);
10*a8802567SValeriy Savchenko 
11*a8802567SValeriy Savchenko int index;
12*a8802567SValeriy Savchenko 
13*a8802567SValeriy Savchenko // We want to check here that the notes about the origins of the null pointer
14*a8802567SValeriy Savchenko // (array[index] = foo()) will get to the final report.
15*a8802567SValeriy Savchenko //
16*a8802567SValeriy Savchenko // The analyzer used to drop exploded nodes for array subscripts when it was
17*a8802567SValeriy Savchenko // time to collect redundant nodes. This GC-like mechanism kicks in only when
18*a8802567SValeriy Savchenko // the exploded graph is large enough (>1K nodes). For this reason, 'index'
19*a8802567SValeriy Savchenko // is a global variable, and the sink point is inside of a loop.
20*a8802567SValeriy Savchenko 
test()21*a8802567SValeriy Savchenko void test() {
22*a8802567SValeriy Savchenko   A *array[42];
23*a8802567SValeriy Savchenko   A *found;
24*a8802567SValeriy Savchenko 
25*a8802567SValeriy Savchenko   for (index = 0; (array[index] = foo()); ++index) { // expected-note {{Loop condition is false. Execution continues on line 34}}
26*a8802567SValeriy Savchenko     // expected-note@-1 {{Value assigned to 'index'}}
27*a8802567SValeriy Savchenko     // expected-note@-2 {{Assigning value}}
28*a8802567SValeriy Savchenko     // expected-note@-3 {{Assuming pointer value is null}}
29*a8802567SValeriy Savchenko     if (array[0])
30*a8802567SValeriy Savchenko       break;
31*a8802567SValeriy Savchenko   }
32*a8802567SValeriy Savchenko 
33*a8802567SValeriy Savchenko   do {
34*a8802567SValeriy Savchenko     found = array[index]; // expected-note {{Null pointer value stored to 'found'}}
35*a8802567SValeriy Savchenko 
36*a8802567SValeriy Savchenko     if (found->method()) // expected-warning {{Called C++ object pointer is null [core.CallAndMessage]}}
37*a8802567SValeriy Savchenko       // expected-note@-1 {{Called C++ object pointer is null}}
38*a8802567SValeriy Savchenko       bar(found);
39*a8802567SValeriy Savchenko   } while (--index);
40*a8802567SValeriy Savchenko }
41