189a1d03eSRichard // RUN: %check_clang_tidy %s bugprone-throw-keyword-missing %t -- -- -fexceptions 289a1d03eSRichard 389a1d03eSRichard namespace std { 489a1d03eSRichard 589a1d03eSRichard // std::string declaration (taken from test/clang-tidy/readability-redundant-string-cstr-msvc.cpp). 689a1d03eSRichard template <typename T> 789a1d03eSRichard class allocator {}; 889a1d03eSRichard template <typename T> 989a1d03eSRichard class char_traits {}; 1089a1d03eSRichard template <typename C, typename T = std::char_traits<C>, typename A = std::allocator<C>> 1189a1d03eSRichard struct basic_string { 1289a1d03eSRichard basic_string(); 1389a1d03eSRichard basic_string(const basic_string &); 1489a1d03eSRichard // MSVC headers define two constructors instead of using optional arguments. 1589a1d03eSRichard basic_string(const C *); 1689a1d03eSRichard basic_string(const C *, const A &); 1789a1d03eSRichard ~basic_string(); 1889a1d03eSRichard }; 1989a1d03eSRichard typedef basic_string<char> string; 2089a1d03eSRichard typedef basic_string<wchar_t> wstring; 2189a1d03eSRichard 2289a1d03eSRichard // std::exception and std::runtime_error declaration. 2389a1d03eSRichard struct exception { 2489a1d03eSRichard exception(); 2589a1d03eSRichard exception(const exception &other); 2689a1d03eSRichard virtual ~exception(); 2789a1d03eSRichard }; 2889a1d03eSRichard 2989a1d03eSRichard struct runtime_error : public exception { 3089a1d03eSRichard explicit runtime_error(const std::string &what_arg); 3189a1d03eSRichard }; 3289a1d03eSRichard 3389a1d03eSRichard } // namespace std 3489a1d03eSRichard 3589a1d03eSRichard // The usage of this class should never emit a warning. 3689a1d03eSRichard struct RegularClass {}; 3789a1d03eSRichard 3889a1d03eSRichard // Class name contains the substring "exception", in certain cases using this class should emit a warning. 3989a1d03eSRichard struct RegularException { 4089a1d03eSRichard RegularException() {} 4189a1d03eSRichard 4289a1d03eSRichard // Constructors with a single argument are treated differently (cxxFunctionalCastExpr). 4389a1d03eSRichard RegularException(int) {} 4489a1d03eSRichard }; 4589a1d03eSRichard 4689a1d03eSRichard // -------------- 4789a1d03eSRichard 4889a1d03eSRichard void stdExceptionNotTrownTest(int i) { 4989a1d03eSRichard if (i < 0) 5089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception object created but not thrown; did you mean 'throw {{.*}}'? [bugprone-throw-keyword-missing] 5189a1d03eSRichard std::exception(); 5289a1d03eSRichard 5389a1d03eSRichard if (i > 0) 5489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception 5589a1d03eSRichard std::runtime_error("Unexpected argument"); 5689a1d03eSRichard } 5789a1d03eSRichard 5889a1d03eSRichard void stdExceptionThrownTest(int i) { 5989a1d03eSRichard if (i < 0) 6089a1d03eSRichard throw std::exception(); 6189a1d03eSRichard 6289a1d03eSRichard if (i > 0) 6389a1d03eSRichard throw std::runtime_error("Unexpected argument"); 6489a1d03eSRichard } 6589a1d03eSRichard 6689a1d03eSRichard void regularClassNotThrownTest(int i) { 6789a1d03eSRichard if (i < 0) 6889a1d03eSRichard RegularClass(); 6989a1d03eSRichard } 7089a1d03eSRichard 7189a1d03eSRichard void regularClassThrownTest(int i) { 7289a1d03eSRichard if (i < 0) 7389a1d03eSRichard throw RegularClass(); 7489a1d03eSRichard } 7589a1d03eSRichard 7689a1d03eSRichard void nameContainsExceptionNotThrownTest(int i) { 7789a1d03eSRichard if (i < 0) 7889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception 7989a1d03eSRichard RegularException(); 8089a1d03eSRichard 8189a1d03eSRichard if (i > 0) 8289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception 8389a1d03eSRichard RegularException(5); 8489a1d03eSRichard } 8589a1d03eSRichard 8689a1d03eSRichard void nameContainsExceptionThrownTest(int i) { 8789a1d03eSRichard if (i < 0) 8889a1d03eSRichard throw RegularException(); 8989a1d03eSRichard 9089a1d03eSRichard if (i > 0) 9189a1d03eSRichard throw RegularException(5); 9289a1d03eSRichard } 9389a1d03eSRichard 9489a1d03eSRichard template <class Exception> 9589a1d03eSRichard void f(int i, Exception excToBeThrown) {} 9689a1d03eSRichard 9789a1d03eSRichard template <class SomeType> 9889a1d03eSRichard void templ(int i) { 9989a1d03eSRichard if (i > 0) 10089a1d03eSRichard SomeType(); 10189a1d03eSRichard } 10289a1d03eSRichard 10389a1d03eSRichard void funcCallWithTempExcTest() { 10489a1d03eSRichard f(5, RegularException()); 10589a1d03eSRichard 10689a1d03eSRichard templ<RegularException>(4); 10789a1d03eSRichard templ<RegularClass>(4); 10889a1d03eSRichard } 10989a1d03eSRichard 11089a1d03eSRichard // Global variable initialization test. 11189a1d03eSRichard RegularException exc = RegularException(); 11289a1d03eSRichard RegularException *excptr = new RegularException(); 11389a1d03eSRichard 11489a1d03eSRichard void localVariableInitTest() { 11589a1d03eSRichard RegularException exc = RegularException(); 11689a1d03eSRichard RegularException *excptr = new RegularException(); 11789a1d03eSRichard } 11889a1d03eSRichard 11989a1d03eSRichard class CtorInitializerListTest { 12089a1d03eSRichard RegularException exc; 12189a1d03eSRichard RegularException exc2{}; 12289a1d03eSRichard 12389a1d03eSRichard CtorInitializerListTest() : exc(RegularException()) {} 12489a1d03eSRichard 12589a1d03eSRichard CtorInitializerListTest(int) try : exc(RegularException()) { 12689a1d03eSRichard // Constructor body 12789a1d03eSRichard } catch (...) { 12889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception 12989a1d03eSRichard RegularException(); 13089a1d03eSRichard } 13189a1d03eSRichard 13289a1d03eSRichard CtorInitializerListTest(float); 13389a1d03eSRichard }; 13489a1d03eSRichard 13589a1d03eSRichard CtorInitializerListTest::CtorInitializerListTest(float) try : exc(RegularException()) { 13689a1d03eSRichard // Constructor body 13789a1d03eSRichard } catch (...) { 13889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: suspicious exception 13989a1d03eSRichard RegularException(); 14089a1d03eSRichard } 14189a1d03eSRichard 142*69fb9bcdSCarlos Galvez namespace GH115055 { 143*69fb9bcdSCarlos Galvez class CtorInitializerListTest2 { 144*69fb9bcdSCarlos Galvez public: 145*69fb9bcdSCarlos Galvez CtorInitializerListTest2() {} 146*69fb9bcdSCarlos Galvez private: 147*69fb9bcdSCarlos Galvez RegularException exc{}; 148*69fb9bcdSCarlos Galvez }; 149*69fb9bcdSCarlos Galvez } // namespace GH115055 150*69fb9bcdSCarlos Galvez 15189a1d03eSRichard RegularException funcReturningExceptionTest(int i) { 15289a1d03eSRichard return RegularException(); 15389a1d03eSRichard } 15489a1d03eSRichard 15589a1d03eSRichard void returnedValueTest() { 15689a1d03eSRichard funcReturningExceptionTest(3); 15789a1d03eSRichard } 15889a1d03eSRichard 15989a1d03eSRichard struct ClassBracedInitListTest { 16089a1d03eSRichard ClassBracedInitListTest(RegularException exc) {} 16189a1d03eSRichard }; 16289a1d03eSRichard 16389a1d03eSRichard void foo(RegularException, ClassBracedInitListTest) {} 16489a1d03eSRichard 16589a1d03eSRichard void bracedInitListTest() { 16689a1d03eSRichard RegularException exc{}; 16789a1d03eSRichard ClassBracedInitListTest test = {RegularException()}; 16889a1d03eSRichard foo({}, {RegularException()}); 16989a1d03eSRichard } 17089a1d03eSRichard 17189a1d03eSRichard typedef std::exception ERROR_BASE; 17289a1d03eSRichard class RegularError : public ERROR_BASE {}; 17389a1d03eSRichard 17489a1d03eSRichard void typedefTest() { 17589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: suspicious exception 17689a1d03eSRichard RegularError(); 17789a1d03eSRichard } 17889a1d03eSRichard 17989a1d03eSRichard struct ExceptionRAII { 18089a1d03eSRichard ExceptionRAII() {} 18189a1d03eSRichard ~ExceptionRAII() {} 18289a1d03eSRichard }; 18389a1d03eSRichard 18489a1d03eSRichard void exceptionRAIITest() { 18589a1d03eSRichard ExceptionRAII E; 18689a1d03eSRichard } 18789a1d03eSRichard 18889a1d03eSRichard namespace std { 18989a1d03eSRichard typedef decltype(sizeof(void*)) size_t; 19089a1d03eSRichard } 19189a1d03eSRichard 19289a1d03eSRichard void* operator new(std::size_t, void*); 19389a1d03eSRichard 19489a1d03eSRichard void placeMentNewTest() { 19589a1d03eSRichard alignas(RegularException) unsigned char expr[sizeof(RegularException)]; 19689a1d03eSRichard new (expr) RegularException{}; 19789a1d03eSRichard } 198