1// RUN: %clang_cc1 %s -fcxx-exceptions -fexceptions -fsyntax-only -verify -fblocks -std=c++11 -Wunreachable-code-aggressive -Wno-unused-value -Wno-tautological-compare 2 3int &halt() __attribute__((noreturn)); 4int &live(); 5int dead(); 6int liveti() throw(int); 7int (*livetip)() throw(int); 8 9int test1() { 10 try { 11 live(); 12 } catch (int i) { 13 live(); 14 } 15 return 1; 16} 17 18void test2() { 19 try { 20 live(); 21 } catch (int i) { 22 live(); 23 } 24 try { 25 liveti(); 26 } catch (int i) { 27 live(); 28 } 29 try { 30 livetip(); 31 } catch (int i) { 32 live(); 33 } 34 throw 1; 35 dead(); // expected-warning {{will never be executed}} 36} 37 38 39void test3() { 40 halt() 41 --; // expected-warning {{will never be executed}} 42 // FIXME: The unreachable part is just the '?', but really all of this 43 // code is unreachable and shouldn't be separately reported. 44 halt() // expected-warning {{will never be executed}} 45 ? 46 dead() : dead(); 47 live(), 48 float 49 (halt()); // expected-warning {{will never be executed}} 50} 51 52void test4() { 53 struct S { 54 int mem; 55 } s; 56 S &foor(); 57 halt(), foor()// expected-warning {{will never be executed}} 58 .mem; 59} 60 61void test5() { 62 struct S { 63 int mem; 64 } s; 65 S &foonr() __attribute__((noreturn)); 66 foonr() 67 .mem; // expected-warning {{will never be executed}} 68} 69 70void test6() { 71 struct S { 72 ~S() { } 73 S(int i) { } 74 }; 75 live(), 76 S 77 (halt()); // expected-warning {{will never be executed}} 78} 79 80// Don't warn about unreachable code in template instantiations, as 81// they may only be unreachable in that specific instantiation. 82void isUnreachable(); 83 84template <typename T> void test_unreachable_templates() { 85 T::foo(); 86 isUnreachable(); // no-warning 87} 88 89struct TestUnreachableA { 90 static void foo() __attribute__((noreturn)); 91}; 92struct TestUnreachableB { 93 static void foo(); 94}; 95 96void test_unreachable_templates_harness() { 97 test_unreachable_templates<TestUnreachableA>(); 98 test_unreachable_templates<TestUnreachableB>(); 99} 100 101// Do warn about explict template specializations, as they represent 102// actual concrete functions that somebody wrote. 103 104template <typename T> void funcToSpecialize() {} 105template <> void funcToSpecialize<int>() { 106 halt(); 107 dead(); // expected-warning {{will never be executed}} 108} 109 110// Handle 'try' code dominating a dead return. 111enum PR19040_test_return_t 112{ PR19040_TEST_FAILURE }; 113namespace PR19040_libtest 114{ 115 class A { 116 public: 117 ~A (); 118 }; 119} 120PR19040_test_return_t PR19040_fn1 () 121{ 122 try 123 { 124 throw PR19040_libtest::A (); 125 } catch (...) 126 { 127 return PR19040_TEST_FAILURE; 128 } 129 return PR19040_TEST_FAILURE; // expected-warning {{will never be executed}} 130} 131 132__attribute__((noreturn)) 133void raze(); 134 135namespace std { 136template<typename T> struct basic_string { 137 basic_string(const T* x) {} 138 ~basic_string() {}; 139}; 140typedef basic_string<char> string; 141} 142 143std::string testStr() { 144 raze(); 145 return ""; // expected-warning {{'return' will never be executed}} 146} 147 148std::string testStrWarn(const char *s) { 149 raze(); 150 return s; // expected-warning {{will never be executed}} 151} 152 153bool testBool() { 154 raze(); 155 return true; // expected-warning {{'return' will never be executed}} 156} 157 158static const bool ConditionVar = 1; 159int test_global_as_conditionVariable() { 160 if (ConditionVar) 161 return 1; 162 return 0; // no-warning 163} 164 165// Handle unreachable temporary destructors. 166class A { 167public: 168 A(); 169 ~A(); 170}; 171 172__attribute__((noreturn)) 173void raze(const A& x); 174 175void test_with_unreachable_tmp_dtors(int x) { 176 raze(x ? A() : A()); // no-warning 177} 178 179// Test sizeof - sizeof in enum declaration. 180enum { BrownCow = sizeof(long) - sizeof(char) }; 181enum { CowBrown = 8 - 1 }; 182 183 184int test_enum_sizeof_arithmetic() { 185 if (BrownCow) 186 return 1; 187 return 2; 188} 189 190int test_enum_arithmetic() { 191 if (CowBrown) 192 return 1; 193 return 2; // expected-warning {{never be executed}} 194} 195 196int test_arithmetic() { 197 if (8 -1) 198 return 1; 199 return 2; // expected-warning {{never be executed}} 200} 201 202int test_treat_const_bool_local_as_config_value() { 203 const bool controlValue = false; 204 if (!controlValue) 205 return 1; 206 test_treat_const_bool_local_as_config_value(); // no-warning 207 return 0; 208} 209 210int test_treat_non_const_bool_local_as_non_config_value() { 211 bool controlValue = false; 212 if (!controlValue) 213 return 1; 214 // There is no warning here because 'controlValue' isn't really 215 // a control value at all. The CFG will not treat this 216 // branch as unreachable. 217 test_treat_non_const_bool_local_as_non_config_value(); // no-warning 218 return 0; 219} 220 221void test_do_while(int x) { 222 // Handle trivial expressions with 223 // implicit casts to bool. 224 do { 225 break; 226 } while (0); // no-warning 227} 228 229class Frobozz { 230public: 231 Frobozz(int x); 232 ~Frobozz(); 233}; 234 235Frobozz test_return_object(int flag) { 236 return Frobozz(flag); 237 return Frobozz(42); // expected-warning {{'return' will never be executed}} 238} 239 240Frobozz test_return_object_control_flow(int flag) { 241 return Frobozz(flag); 242 return Frobozz(flag ? 42 : 24); // expected-warning {{code will never be executed}} 243} 244 245void somethingToCall(); 246 247static constexpr bool isConstExprConfigValue() { return true; } 248 249int test_const_expr_config_value() { 250 if (isConstExprConfigValue()) { 251 somethingToCall(); 252 return 0; 253 } 254 somethingToCall(); // no-warning 255 return 1; 256} 257int test_const_expr_config_value_2() { 258 if (!isConstExprConfigValue()) { 259 somethingToCall(); // no-warning 260 return 0; 261 } 262 somethingToCall(); 263 return 1; 264} 265 266class Frodo { 267public: 268 static const bool aHobbit = true; 269}; 270 271void test_static_class_var() { 272 if (Frodo::aHobbit) 273 somethingToCall(); 274 else 275 somethingToCall(); // no-warning 276} 277 278void test_static_class_var(Frodo &F) { 279 if (F.aHobbit) 280 somethingToCall(); 281 else 282 somethingToCall(); // no-warning 283} 284 285void test_unreachable_for_null_increment() { 286 for (unsigned i = 0; i < 10 ; ) // no-warning 287 break; 288} 289 290void test_unreachable_forrange_increment() { 291 int x[10] = { 0 }; 292 for (auto i : x) { // expected-warning {{loop will run at most once (loop increment never executed)}} 293 break; 294 } 295} 296 297void calledFun() {} 298 299// Test "silencing" with parentheses. 300void test_with_paren_silencing(int x) { 301 if (false) calledFun(); // expected-warning {{will never be executed}} expected-note {{silence by adding parentheses to mark code as explicitly dead}} 302 if ((false)) calledFun(); // no-warning 303 304 if (true) // expected-note {{silence by adding parentheses to mark code as explicitly dead}} 305 calledFun(); 306 else 307 calledFun(); // expected-warning {{will never be executed}} 308 309 if ((true)) 310 calledFun(); 311 else 312 calledFun(); // no-warning 313 314 if (!true) // expected-note {{silence by adding parentheses to mark code as explicitly dead}} 315 calledFun(); // expected-warning {{code will never be executed}} 316 else 317 calledFun(); 318 319 if ((!true)) 320 calledFun(); // no-warning 321 else 322 calledFun(); 323 324 if (!(true)) 325 calledFun(); // no-warning 326 else 327 calledFun(); 328} 329 330void test_with_paren_silencing_impcast(int x) { 331 if (0) calledFun(); // expected-warning {{will never be executed}} expected-note {{silence by adding parentheses to mark code as explicitly dead}} 332 if ((0)) calledFun(); // no-warning 333 334 if (1) // expected-note {{silence by adding parentheses to mark code as explicitly dead}} 335 calledFun(); 336 else 337 calledFun(); // expected-warning {{will never be executed}} 338 339 if ((1)) 340 calledFun(); 341 else 342 calledFun(); // no-warning 343 344 if (!1) // expected-note {{silence by adding parentheses to mark code as explicitly dead}} 345 calledFun(); // expected-warning {{code will never be executed}} 346 else 347 calledFun(); 348 349 if ((!1)) 350 calledFun(); // no-warning 351 else 352 calledFun(); 353 354 if (!(1)) 355 calledFun(); // no-warning 356 else 357 calledFun(); 358} 359 360void tautological_compare(bool x, int y) { 361 if (x > 10) // expected-note {{silence}} 362 calledFun(); // expected-warning {{will never be executed}} 363 if (10 < x) // expected-note {{silence}} 364 calledFun(); // expected-warning {{will never be executed}} 365 if (x == 10) // expected-note {{silence}} 366 calledFun(); // expected-warning {{will never be executed}} 367 368 if (x < 10) // expected-note {{silence}} 369 calledFun(); 370 else 371 calledFun(); // expected-warning {{will never be executed}} 372 if (10 > x) // expected-note {{silence}} 373 calledFun(); 374 else 375 calledFun(); // expected-warning {{will never be executed}} 376 if (x != 10) // expected-note {{silence}} 377 calledFun(); 378 else 379 calledFun(); // expected-warning {{will never be executed}} 380 381 if (y != 5 && y == 5) // expected-note {{silence}} 382 calledFun(); // expected-warning {{will never be executed}} 383 384 if (y > 5 && y < 4) // expected-note {{silence}} 385 calledFun(); // expected-warning {{will never be executed}} 386 387 if (y < 10 || y > 5) // expected-note {{silence}} 388 calledFun(); 389 else 390 calledFun(); // expected-warning {{will never be executed}} 391 392 // TODO: Extend warning to the following code: 393 if (x < -1) 394 calledFun(); 395 if (x == -1) 396 calledFun(); 397 398 if (x != -1) 399 calledFun(); 400 else 401 calledFun(); 402 if (-1 > x) 403 calledFun(); 404 else 405 calledFun(); 406 407 if (y == -1 && y != -1) 408 calledFun(); 409} 410