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