1 // RUN: %check_clang_tidy -std=c++11,c++14 %s bugprone-exception-escape %t -- \ 2 // RUN: -config="{CheckOptions: [ \ 3 // RUN: {key: bugprone-exception-escape.IgnoredExceptions, value: 'ignored1,ignored2'}, \ 4 // RUN: {key: bugprone-exception-escape.FunctionsThatShouldNotThrow, value: 'enabled1,enabled2,enabled3'} \ 5 // RUN: ]}" \ 6 // RUN: -- -fexceptions 7 8 struct throwing_destructor { ~throwing_destructorthrowing_destructor9 ~throwing_destructor() { 10 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: an exception may be thrown in function '~throwing_destructor' which should not throw exceptions 11 throw 1; 12 } 13 }; 14 15 struct throwing_move_constructor { throwing_move_constructorthrowing_move_constructor16 throwing_move_constructor(throwing_move_constructor&&) { 17 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: an exception may be thrown in function 'throwing_move_constructor' which should not throw exceptions 18 throw 1; 19 } 20 }; 21 22 struct throwing_move_assignment { operator =throwing_move_assignment23 throwing_move_assignment& operator=(throwing_move_assignment&&) { 24 // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: an exception may be thrown in function 'operator=' which should not throw exceptions 25 throw 1; 26 } 27 }; 28 throwing_noexcept()29void throwing_noexcept() noexcept { 30 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throwing_noexcept' which should not throw exceptions 31 throw 1; 32 } 33 throwing_throw_nothing()34void throwing_throw_nothing() throw() { 35 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throwing_throw_nothing' which should not throw exceptions 36 throw 1; 37 } 38 throw_and_catch()39void throw_and_catch() noexcept { 40 // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throw_and_catch' which should not throw exceptions 41 try { 42 throw 1; 43 } catch(int &) { 44 } 45 } 46 throw_and_catch_some(int n)47void throw_and_catch_some(int n) noexcept { 48 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throw_and_catch_some' which should not throw exceptions 49 try { 50 if (n) throw 1; 51 throw 1.1; 52 } catch(int &) { 53 } 54 } 55 throw_and_catch_each(int n)56void throw_and_catch_each(int n) noexcept { 57 // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throw_and_catch_each' which should not throw exceptions 58 try { 59 if (n) throw 1; 60 throw 1.1; 61 } catch(int &) { 62 } catch(double &) { 63 } 64 } 65 throw_and_catch_all(int n)66void throw_and_catch_all(int n) noexcept { 67 // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throw_and_catch_all' which should not throw exceptions 68 try { 69 if (n) throw 1; 70 throw 1.1; 71 } catch(...) { 72 } 73 } 74 throw_and_rethrow()75void throw_and_rethrow() noexcept { 76 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throw_and_rethrow' which should not throw exceptions 77 try { 78 throw 1; 79 } catch(int &) { 80 throw; 81 } 82 } 83 throw_catch_throw()84void throw_catch_throw() noexcept { 85 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throw_catch_throw' which should not throw exceptions 86 try { 87 throw 1; 88 } catch(int &) { 89 throw 2; 90 } 91 } 92 throw_catch_rethrow_the_rest(int n)93void throw_catch_rethrow_the_rest(int n) noexcept { 94 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throw_catch_rethrow_the_rest' which should not throw exceptions 95 try { 96 if (n) throw 1; 97 throw 1.1; 98 } catch(int &) { 99 } catch(...) { 100 throw; 101 } 102 } 103 104 class base {}; 105 class derived: public base {}; 106 throw_derived_catch_base()107void throw_derived_catch_base() noexcept { 108 // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throw_derived_catch_base' which should not throw exceptions 109 try { 110 throw derived(); 111 } catch(base &) { 112 } 113 } 114 try_nested_try(int n)115void try_nested_try(int n) noexcept { 116 // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'try_nested_try' which should not throw exceptions 117 try { 118 try { 119 if (n) throw 1; 120 throw 1.1; 121 } catch(int &) { 122 } 123 } catch(double &) { 124 } 125 } 126 bad_try_nested_try(int n)127void bad_try_nested_try(int n) noexcept { 128 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'bad_try_nested_try' which should not throw exceptions 129 try { 130 if (n) throw 1; 131 try { 132 throw 1.1; 133 } catch(int &) { 134 } 135 } catch(double &) { 136 } 137 } 138 try_nested_catch()139void try_nested_catch() noexcept { 140 // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'try_nested_catch' which should not throw exceptions 141 try { 142 try { 143 throw 1; 144 } catch(int &) { 145 throw 1.1; 146 } 147 } catch(double &) { 148 } 149 } 150 catch_nested_try()151void catch_nested_try() noexcept { 152 // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'catch_nested_try' which should not throw exceptions 153 try { 154 throw 1; 155 } catch(int &) { 156 try { 157 throw 1; 158 } catch(int &) { 159 } 160 } 161 } 162 bad_catch_nested_try()163void bad_catch_nested_try() noexcept { 164 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'bad_catch_nested_try' which should not throw exceptions 165 try { 166 throw 1; 167 } catch(int &) { 168 try { 169 throw 1.1; 170 } catch(int &) { 171 } 172 } catch(double &) { 173 } 174 } 175 implicit_int_thrower()176void implicit_int_thrower() { 177 throw 1; 178 } 179 180 void explicit_int_thrower() throw(int); 181 indirect_implicit()182void indirect_implicit() noexcept { 183 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'indirect_implicit' which should not throw exceptions 184 implicit_int_thrower(); 185 } 186 indirect_explicit()187void indirect_explicit() noexcept { 188 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'indirect_explicit' which should not throw exceptions 189 explicit_int_thrower(); 190 } 191 indirect_catch()192void indirect_catch() noexcept { 193 // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'indirect_catch' which should not throw exceptions 194 try { 195 implicit_int_thrower(); 196 } catch(int&) { 197 } 198 } 199 200 template<typename T> dependent_throw()201void dependent_throw() noexcept(sizeof(T)<4) { 202 // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'dependent_throw' which should not throw exceptions 203 if (sizeof(T) > 4) 204 throw 1; 205 } 206 swap(int &,int &)207void swap(int&, int&) { 208 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'swap' which should not throw exceptions 209 throw 1; 210 } 211 212 namespace std { 213 class bad_alloc {}; 214 } 215 alloc()216void alloc() { 217 throw std::bad_alloc(); 218 } 219 allocator()220void allocator() noexcept { 221 // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'allocator' which should not throw exceptions 222 alloc(); 223 } 224 enabled1()225void enabled1() { 226 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'enabled1' which should not throw exceptions 227 throw 1; 228 } 229 enabled2()230void enabled2() { 231 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'enabled2' which should not throw exceptions 232 enabled1(); 233 } 234 enabled3()235void enabled3() { 236 // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'enabled3' which should not throw exceptions 237 try { 238 enabled1(); 239 } catch(...) { 240 } 241 } 242 243 class ignored1 {}; 244 class ignored2 {}; 245 this_does_not_count()246void this_does_not_count() noexcept { 247 // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'this_does_not_count' which should not throw exceptions 248 throw ignored1(); 249 } 250 this_does_not_count_either(int n)251void this_does_not_count_either(int n) noexcept { 252 // CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'this_does_not_count_either' which should not throw exceptions 253 try { 254 throw 1; 255 if (n) throw ignored2(); 256 } catch(int &) { 257 } 258 } 259 this_counts(int n)260void this_counts(int n) noexcept { 261 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'this_counts' which should not throw exceptions 262 if (n) throw 1; 263 throw ignored1(); 264 } 265 thrower(int n)266void thrower(int n) { 267 throw n; 268 } 269 directly_recursive(int n)270int directly_recursive(int n) noexcept { 271 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'directly_recursive' which should not throw exceptions 272 if (n == 0) 273 thrower(n); 274 return directly_recursive(n); 275 } 276 277 int indirectly_recursive(int n) noexcept; 278 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'indirectly_recursive' which should not throw exceptions 279 recursion_helper(int n)280int recursion_helper(int n) { 281 indirectly_recursive(n); 282 } 283 indirectly_recursive(int n)284int indirectly_recursive(int n) noexcept { 285 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'indirectly_recursive' which should not throw exceptions 286 if (n == 0) 287 thrower(n); 288 return recursion_helper(n); 289 } 290 main()291int main() { 292 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'main' which should not throw exceptions 293 throw 1; 294 return 0; 295 } 296