1 // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -analyze -analyzer-checker=deadcode.DeadStores -verify -Wno-unreachable-code %s
2 // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -analyze -analyzer-store=region -analyzer-constraints=range -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