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