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