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