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