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