1 // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fblocks -std=c++11 -analyze -analyzer-checker=deadcode.DeadStores -verify -Wno-unreachable-code %s 2 // 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 4 //===----------------------------------------------------------------------===// 5 // Basic dead store checking (but in C++ mode). 6 //===----------------------------------------------------------------------===// 7 8 int j; test1()9void 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)33int 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()60void test2_b() { 61 TestTemp::row<const char*> x; // no-warning 62 } 63 64 //===----------------------------------------------------------------------===// 65 // Test references. 66 //===----------------------------------------------------------------------===// 67 test3_a(int x)68void test3_a(int x) { 69 x = x + 1; // expected-warning{{never read}} 70 } 71 test3_b(int & x)72void test3_b(int &x) { 73 x = x + 1; // no-warninge 74 } 75 test3_c(int x)76void 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)83void test3_d(int &x) { 84 int &y = x; 85 ++y; // no-warning 86 } 87 test3_e(int & x)88void test3_e(int &x) { 89 int &y = x; 90 } 91 92 //===----------------------------------------------------------------------===// 93 // Dead stores involving 'new' 94 //===----------------------------------------------------------------------===// 95 test_new(unsigned n)96static 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()117int 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()132void 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()142void 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()154void 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)164template <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()173int 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)178void 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)184void 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)195int 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