xref: /aosp_15_r20/external/clang/test/Analysis/dead-stores.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fblocks -std=c++11 -analyze -analyzer-checker=deadcode.DeadStores -verify -Wno-unreachable-code %s
2*67e74705SXin Li // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fblocks -std=c++11 -analyze -analyzer-store=region -analyzer-constraints=range -analyzer-checker=deadcode.DeadStores -verify -Wno-unreachable-code %s
3*67e74705SXin Li 
4*67e74705SXin Li //===----------------------------------------------------------------------===//
5*67e74705SXin Li // Basic dead store checking (but in C++ mode).
6*67e74705SXin Li //===----------------------------------------------------------------------===//
7*67e74705SXin Li 
8*67e74705SXin Li int j;
test1()9*67e74705SXin Li void test1() {
10*67e74705SXin Li   int x = 4;
11*67e74705SXin Li 
12*67e74705SXin Li   x = x + 1; // expected-warning{{never read}}
13*67e74705SXin Li 
14*67e74705SXin Li   switch (j) {
15*67e74705SXin Li   case 1:
16*67e74705SXin Li     throw 1;
17*67e74705SXin Li     (void)x;
18*67e74705SXin Li     break;
19*67e74705SXin Li   }
20*67e74705SXin Li }
21*67e74705SXin Li 
22*67e74705SXin Li //===----------------------------------------------------------------------===//
23*67e74705SXin Li // Dead store checking involving constructors.
24*67e74705SXin Li //===----------------------------------------------------------------------===//
25*67e74705SXin Li 
26*67e74705SXin Li class Test2 {
27*67e74705SXin Li   int &x;
28*67e74705SXin Li public:
Test2(int & y)29*67e74705SXin Li   Test2(int &y) : x(y) {}
~Test2()30*67e74705SXin Li   ~Test2() { ++x; }
31*67e74705SXin Li };
32*67e74705SXin Li 
test2(int x)33*67e74705SXin Li int test2(int x) {
34*67e74705SXin Li   { Test2 a(x); } // no-warning
35*67e74705SXin Li   return x;
36*67e74705SXin Li }
37*67e74705SXin Li 
38*67e74705SXin Li //===----------------------------------------------------------------------===//
39*67e74705SXin Li // Dead store checking involving CXXTemporaryExprs
40*67e74705SXin Li //===----------------------------------------------------------------------===//
41*67e74705SXin Li 
42*67e74705SXin Li namespace TestTemp {
43*67e74705SXin Li   template<typename _Tp>
44*67e74705SXin Li   class pencil {
45*67e74705SXin Li   public:
~pencil()46*67e74705SXin Li     ~pencil() throw() {}
47*67e74705SXin Li   };
48*67e74705SXin Li   template<typename _Tp, typename _Number2> struct _Row_base {
_Row_baseTestTemp::_Row_base49*67e74705SXin Li     _Row_base(const pencil<_Tp>& x) {}
50*67e74705SXin Li   };
51*67e74705SXin Li   template<typename _Tp, typename _Number2 = TestTemp::pencil<_Tp> >
52*67e74705SXin Li   class row : protected _Row_base<_Tp, _Number2>     {
53*67e74705SXin Li     typedef _Row_base<_Tp, _Number2> _Base;
54*67e74705SXin Li     typedef _Number2 pencil_type;
55*67e74705SXin Li   public:
row(const pencil_type & __a=pencil_type ())56*67e74705SXin Li     explicit row(const pencil_type& __a = pencil_type()) : _Base(__a) {}
57*67e74705SXin Li   };
58*67e74705SXin Li }
59*67e74705SXin Li 
test2_b()60*67e74705SXin Li void test2_b() {
61*67e74705SXin Li   TestTemp::row<const char*> x; // no-warning
62*67e74705SXin Li }
63*67e74705SXin Li 
64*67e74705SXin Li //===----------------------------------------------------------------------===//
65*67e74705SXin Li // Test references.
66*67e74705SXin Li //===----------------------------------------------------------------------===//
67*67e74705SXin Li 
test3_a(int x)68*67e74705SXin Li void test3_a(int x) {
69*67e74705SXin Li    x = x + 1; // expected-warning{{never read}}
70*67e74705SXin Li }
71*67e74705SXin Li 
test3_b(int & x)72*67e74705SXin Li void test3_b(int &x) {
73*67e74705SXin Li   x = x + 1; // no-warninge
74*67e74705SXin Li }
75*67e74705SXin Li 
test3_c(int x)76*67e74705SXin Li void test3_c(int x) {
77*67e74705SXin Li   int &y = x;
78*67e74705SXin Li   // Shows the limitation of dead stores tracking.  The write is really
79*67e74705SXin Li   // dead since the value cannot escape the function.
80*67e74705SXin Li   ++y; // no-warning
81*67e74705SXin Li }
82*67e74705SXin Li 
test3_d(int & x)83*67e74705SXin Li void test3_d(int &x) {
84*67e74705SXin Li   int &y = x;
85*67e74705SXin Li   ++y; // no-warning
86*67e74705SXin Li }
87*67e74705SXin Li 
test3_e(int & x)88*67e74705SXin Li void test3_e(int &x) {
89*67e74705SXin Li   int &y = x;
90*67e74705SXin Li }
91*67e74705SXin Li 
92*67e74705SXin Li //===----------------------------------------------------------------------===//
93*67e74705SXin Li // Dead stores involving 'new'
94*67e74705SXin Li //===----------------------------------------------------------------------===//
95*67e74705SXin Li 
test_new(unsigned n)96*67e74705SXin Li static void test_new(unsigned n) {
97*67e74705SXin Li   char **p = new char* [n]; // expected-warning{{never read}}
98*67e74705SXin Li }
99*67e74705SXin Li 
100*67e74705SXin Li //===----------------------------------------------------------------------===//
101*67e74705SXin Li // Dead stores in namespaces.
102*67e74705SXin Li //===----------------------------------------------------------------------===//
103*67e74705SXin Li 
104*67e74705SXin Li namespace foo {
test_4(int x)105*67e74705SXin Li   int test_4(int x) {
106*67e74705SXin Li     x = 2; // expected-warning{{Value stored to 'x' is never read}}
107*67e74705SXin Li     x = 2;
108*67e74705SXin Li     return x;
109*67e74705SXin Li   }
110*67e74705SXin Li }
111*67e74705SXin Li 
112*67e74705SXin Li //===----------------------------------------------------------------------===//
113*67e74705SXin Li // Dead stores in with EH code.
114*67e74705SXin Li //===----------------------------------------------------------------------===//
115*67e74705SXin Li 
116*67e74705SXin Li void test_5_Aux();
test_5()117*67e74705SXin Li int test_5() {
118*67e74705SXin Li   int x = 0;
119*67e74705SXin Li   try {
120*67e74705SXin Li     x = 2; // no-warning
121*67e74705SXin Li     test_5_Aux();
122*67e74705SXin Li   }
123*67e74705SXin Li   catch (int z) {
124*67e74705SXin Li     return x + z;
125*67e74705SXin Li   }
126*67e74705SXin Li   return 1;
127*67e74705SXin Li }
128*67e74705SXin Li 
129*67e74705SXin Li 
130*67e74705SXin Li int test_6_aux(unsigned x);
131*67e74705SXin Li 
test_6()132*67e74705SXin Li void test_6() {
133*67e74705SXin Li   unsigned currDestLen = 0;  // no-warning
134*67e74705SXin Li   try {
135*67e74705SXin Li     while (test_6_aux(currDestLen)) {
136*67e74705SXin Li       currDestLen += 2; // no-warning
137*67e74705SXin Li     }
138*67e74705SXin Li   }
139*67e74705SXin Li   catch (void *) {}
140*67e74705SXin Li }
141*67e74705SXin Li 
test_6b()142*67e74705SXin Li void test_6b() {
143*67e74705SXin Li   unsigned currDestLen = 0;  // no-warning
144*67e74705SXin Li   try {
145*67e74705SXin Li     while (test_6_aux(currDestLen)) {
146*67e74705SXin Li       currDestLen += 2; // expected-warning {{Value stored to 'currDestLen' is never read}}
147*67e74705SXin Li       break;
148*67e74705SXin Li     }
149*67e74705SXin Li   }
150*67e74705SXin Li   catch (void *) {}
151*67e74705SXin Li }
152*67e74705SXin Li 
153*67e74705SXin Li 
testCXX11Using()154*67e74705SXin Li void testCXX11Using() {
155*67e74705SXin Li   using Int = int;
156*67e74705SXin Li   Int value;
157*67e74705SXin Li   value = 1; // expected-warning {{never read}}
158*67e74705SXin Li }
159*67e74705SXin Li 
160*67e74705SXin Li //===----------------------------------------------------------------------===//
161*67e74705SXin Li // Dead stores in template instantiations (do not warn).
162*67e74705SXin Li //===----------------------------------------------------------------------===//
163*67e74705SXin Li 
radar13213575_testit(int i)164*67e74705SXin Li template <bool f> int radar13213575_testit(int i) {
165*67e74705SXin Li   int x = 5+i; // warning: Value stored to 'x' during its initialization is never read
166*67e74705SXin Li   int y = 7;
167*67e74705SXin Li   if (f)
168*67e74705SXin Li     return x;
169*67e74705SXin Li   else
170*67e74705SXin Li     return y;
171*67e74705SXin Li }
172*67e74705SXin Li 
radar_13213575()173*67e74705SXin Li int radar_13213575() {
174*67e74705SXin Li   return radar13213575_testit<true>(5) + radar13213575_testit<false>(3);
175*67e74705SXin Li }
176*67e74705SXin Li 
177*67e74705SXin Li template <class T>
test_block_in_dependent_context(typename T::some_t someArray)178*67e74705SXin Li void test_block_in_dependent_context(typename T::some_t someArray) {
179*67e74705SXin Li   ^{
180*67e74705SXin Li      int i = someArray[0]; // no-warning
181*67e74705SXin Li   }();
182*67e74705SXin Li }
183*67e74705SXin Li 
test_block_in_non_dependent_context(int * someArray)184*67e74705SXin Li void test_block_in_non_dependent_context(int *someArray) {
185*67e74705SXin Li   ^{
186*67e74705SXin Li      int i = someArray[0]; // expected-warning {{Value stored to 'i' during its initialization is never read}}
187*67e74705SXin Li   }();
188*67e74705SXin Li }
189*67e74705SXin Li 
190*67e74705SXin Li 
191*67e74705SXin Li //===----------------------------------------------------------------------===//
192*67e74705SXin Li // Dead store checking involving lambdas.
193*67e74705SXin Li //===----------------------------------------------------------------------===//
194*67e74705SXin Li 
basicLambda(int i,int j)195*67e74705SXin Li int basicLambda(int i, int j) {
196*67e74705SXin Li   i = 5; // no warning
197*67e74705SXin Li   j = 6; // no warning
198*67e74705SXin Li   [i] { (void)i; }();
199*67e74705SXin Li   [&j] { (void)j; }();
200*67e74705SXin Li   i = 2;
201*67e74705SXin Li   j = 3;
202*67e74705SXin Li   return i + j;
203*67e74705SXin Li }
204*67e74705SXin Li 
205