1 // RUN: %check_clang_tidy %s bugprone-throw-keyword-missing %t -- -- -fexceptions 2 3 namespace std { 4 5 // std::string declaration (taken from test/clang-tidy/readability-redundant-string-cstr-msvc.cpp). 6 template <typename T> 7 class allocator {}; 8 template <typename T> 9 class char_traits {}; 10 template <typename C, typename T = std::char_traits<C>, typename A = std::allocator<C>> 11 struct basic_string { 12 basic_string(); 13 basic_string(const basic_string &); 14 // MSVC headers define two constructors instead of using optional arguments. 15 basic_string(const C *); 16 basic_string(const C *, const A &); 17 ~basic_string(); 18 }; 19 typedef basic_string<char> string; 20 typedef basic_string<wchar_t> wstring; 21 22 // std::exception and std::runtime_error declaration. 23 struct exception { 24 exception(); 25 exception(const exception &other); 26 virtual ~exception(); 27 }; 28 29 struct runtime_error : public exception { 30 explicit runtime_error(const std::string &what_arg); 31 }; 32 33 } // namespace std 34 35 // The usage of this class should never emit a warning. 36 struct RegularClass {}; 37 38 // Class name contains the substring "exception", in certain cases using this class should emit a warning. 39 struct RegularException { 40 RegularException() {} 41 42 // Constructors with a single argument are treated differently (cxxFunctionalCastExpr). 43 RegularException(int) {} 44 }; 45 46 // -------------- 47 48 void stdExceptionNotTrownTest(int i) { 49 if (i < 0) 50 // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception object created but not thrown; did you mean 'throw {{.*}}'? [bugprone-throw-keyword-missing] 51 std::exception(); 52 53 if (i > 0) 54 // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception 55 std::runtime_error("Unexpected argument"); 56 } 57 58 void stdExceptionThrownTest(int i) { 59 if (i < 0) 60 throw std::exception(); 61 62 if (i > 0) 63 throw std::runtime_error("Unexpected argument"); 64 } 65 66 void regularClassNotThrownTest(int i) { 67 if (i < 0) 68 RegularClass(); 69 } 70 71 void regularClassThrownTest(int i) { 72 if (i < 0) 73 throw RegularClass(); 74 } 75 76 void nameContainsExceptionNotThrownTest(int i) { 77 if (i < 0) 78 // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception 79 RegularException(); 80 81 if (i > 0) 82 // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception 83 RegularException(5); 84 } 85 86 void nameContainsExceptionThrownTest(int i) { 87 if (i < 0) 88 throw RegularException(); 89 90 if (i > 0) 91 throw RegularException(5); 92 } 93 94 template <class Exception> 95 void f(int i, Exception excToBeThrown) {} 96 97 template <class SomeType> 98 void templ(int i) { 99 if (i > 0) 100 SomeType(); 101 } 102 103 void funcCallWithTempExcTest() { 104 f(5, RegularException()); 105 106 templ<RegularException>(4); 107 templ<RegularClass>(4); 108 } 109 110 // Global variable initialization test. 111 RegularException exc = RegularException(); 112 RegularException *excptr = new RegularException(); 113 114 void localVariableInitTest() { 115 RegularException exc = RegularException(); 116 RegularException *excptr = new RegularException(); 117 } 118 119 class CtorInitializerListTest { 120 RegularException exc; 121 RegularException exc2{}; 122 123 CtorInitializerListTest() : exc(RegularException()) {} 124 125 CtorInitializerListTest(int) try : exc(RegularException()) { 126 // Constructor body 127 } catch (...) { 128 // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception 129 RegularException(); 130 } 131 132 CtorInitializerListTest(float); 133 }; 134 135 CtorInitializerListTest::CtorInitializerListTest(float) try : exc(RegularException()) { 136 // Constructor body 137 } catch (...) { 138 // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: suspicious exception 139 RegularException(); 140 } 141 142 namespace GH115055 { 143 class CtorInitializerListTest2 { 144 public: 145 CtorInitializerListTest2() {} 146 private: 147 RegularException exc{}; 148 }; 149 } // namespace GH115055 150 151 RegularException funcReturningExceptionTest(int i) { 152 return RegularException(); 153 } 154 155 void returnedValueTest() { 156 funcReturningExceptionTest(3); 157 } 158 159 struct ClassBracedInitListTest { 160 ClassBracedInitListTest(RegularException exc) {} 161 }; 162 163 void foo(RegularException, ClassBracedInitListTest) {} 164 165 void bracedInitListTest() { 166 RegularException exc{}; 167 ClassBracedInitListTest test = {RegularException()}; 168 foo({}, {RegularException()}); 169 } 170 171 typedef std::exception ERROR_BASE; 172 class RegularError : public ERROR_BASE {}; 173 174 void typedefTest() { 175 // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: suspicious exception 176 RegularError(); 177 } 178 179 struct ExceptionRAII { 180 ExceptionRAII() {} 181 ~ExceptionRAII() {} 182 }; 183 184 void exceptionRAIITest() { 185 ExceptionRAII E; 186 } 187 188 namespace std { 189 typedef decltype(sizeof(void*)) size_t; 190 } 191 192 void* operator new(std::size_t, void*); 193 194 void placeMentNewTest() { 195 alignas(RegularException) unsigned char expr[sizeof(RegularException)]; 196 new (expr) RegularException{}; 197 } 198