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(); 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: 46 Test2(int &y) : x(y) {} 47 ~Test2() { ++x; } 48 }; 49 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: 63 ~pencil() throw() {} 64 }; 65 template<typename _Tp, typename _Number2> struct _Row_base { 66 _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: 73 explicit row(const pencil_type& __a = pencil_type()) : _Base(__a) {} 74 }; 75 } 76 77 void test2_b() { 78 TestTemp::row<const char*> x; // no-warning 79 } 80 81 //===----------------------------------------------------------------------===// 82 // Test references. 83 //===----------------------------------------------------------------------===// 84 85 void test3_a(int x) { 86 x = x + 1; // non-nested-warning {{never read}} 87 } 88 89 void test3_b(int &x) { 90 x = x + 1; // no-warning 91 } 92 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 100 void test3_d(int &x) { 101 int &y = x; 102 ++y; // no-warning 103 } 104 105 void test3_e(int &x) { 106 int &y = x; 107 } 108 109 //===----------------------------------------------------------------------===// 110 // Dead stores involving 'new' 111 //===----------------------------------------------------------------------===// 112 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 { 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(); 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); 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 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 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 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 187 int radar_13213575() { 188 return radar13213575_testit<true>(5) + radar13213575_testit<false>(3); 189 } 190 191 template <class T> 192 void test_block_in_dependent_context(typename T::some_t someArray) { 193 ^{ 194 int i = someArray[0]; // no-warning 195 }(); 196 } 197 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 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