forked from OSchip/llvm-project
296 lines
8.4 KiB
C++
296 lines
8.4 KiB
C++
// RUN: %check_clang_tidy -std=c++11,c++14 %s bugprone-exception-escape %t -- \
|
|
// RUN: -config="{CheckOptions: [ \
|
|
// RUN: {key: bugprone-exception-escape.IgnoredExceptions, value: 'ignored1,ignored2'}, \
|
|
// RUN: {key: bugprone-exception-escape.FunctionsThatShouldNotThrow, value: 'enabled1,enabled2,enabled3'} \
|
|
// RUN: ]}" \
|
|
// RUN: -- -fexceptions
|
|
|
|
struct throwing_destructor {
|
|
~throwing_destructor() {
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: an exception may be thrown in function '~throwing_destructor' which should not throw exceptions
|
|
throw 1;
|
|
}
|
|
};
|
|
|
|
struct throwing_move_constructor {
|
|
throwing_move_constructor(throwing_move_constructor&&) {
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: an exception may be thrown in function 'throwing_move_constructor' which should not throw exceptions
|
|
throw 1;
|
|
}
|
|
};
|
|
|
|
struct throwing_move_assignment {
|
|
throwing_move_assignment& operator=(throwing_move_assignment&&) {
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: an exception may be thrown in function 'operator=' which should not throw exceptions
|
|
throw 1;
|
|
}
|
|
};
|
|
|
|
void throwing_noexcept() noexcept {
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throwing_noexcept' which should not throw exceptions
|
|
throw 1;
|
|
}
|
|
|
|
void throwing_throw_nothing() throw() {
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throwing_throw_nothing' which should not throw exceptions
|
|
throw 1;
|
|
}
|
|
|
|
void throw_and_catch() noexcept {
|
|
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throw_and_catch' which should not throw exceptions
|
|
try {
|
|
throw 1;
|
|
} catch(int &) {
|
|
}
|
|
}
|
|
|
|
void throw_and_catch_some(int n) noexcept {
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throw_and_catch_some' which should not throw exceptions
|
|
try {
|
|
if (n) throw 1;
|
|
throw 1.1;
|
|
} catch(int &) {
|
|
}
|
|
}
|
|
|
|
void throw_and_catch_each(int n) noexcept {
|
|
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throw_and_catch_each' which should not throw exceptions
|
|
try {
|
|
if (n) throw 1;
|
|
throw 1.1;
|
|
} catch(int &) {
|
|
} catch(double &) {
|
|
}
|
|
}
|
|
|
|
void throw_and_catch_all(int n) noexcept {
|
|
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throw_and_catch_all' which should not throw exceptions
|
|
try {
|
|
if (n) throw 1;
|
|
throw 1.1;
|
|
} catch(...) {
|
|
}
|
|
}
|
|
|
|
void throw_and_rethrow() noexcept {
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throw_and_rethrow' which should not throw exceptions
|
|
try {
|
|
throw 1;
|
|
} catch(int &) {
|
|
throw;
|
|
}
|
|
}
|
|
|
|
void throw_catch_throw() noexcept {
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throw_catch_throw' which should not throw exceptions
|
|
try {
|
|
throw 1;
|
|
} catch(int &) {
|
|
throw 2;
|
|
}
|
|
}
|
|
|
|
void throw_catch_rethrow_the_rest(int n) noexcept {
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throw_catch_rethrow_the_rest' which should not throw exceptions
|
|
try {
|
|
if (n) throw 1;
|
|
throw 1.1;
|
|
} catch(int &) {
|
|
} catch(...) {
|
|
throw;
|
|
}
|
|
}
|
|
|
|
class base {};
|
|
class derived: public base {};
|
|
|
|
void throw_derived_catch_base() noexcept {
|
|
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'throw_derived_catch_base' which should not throw exceptions
|
|
try {
|
|
throw derived();
|
|
} catch(base &) {
|
|
}
|
|
}
|
|
|
|
void try_nested_try(int n) noexcept {
|
|
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'try_nested_try' which should not throw exceptions
|
|
try {
|
|
try {
|
|
if (n) throw 1;
|
|
throw 1.1;
|
|
} catch(int &) {
|
|
}
|
|
} catch(double &) {
|
|
}
|
|
}
|
|
|
|
void bad_try_nested_try(int n) noexcept {
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'bad_try_nested_try' which should not throw exceptions
|
|
try {
|
|
if (n) throw 1;
|
|
try {
|
|
throw 1.1;
|
|
} catch(int &) {
|
|
}
|
|
} catch(double &) {
|
|
}
|
|
}
|
|
|
|
void try_nested_catch() noexcept {
|
|
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'try_nested_catch' which should not throw exceptions
|
|
try {
|
|
try {
|
|
throw 1;
|
|
} catch(int &) {
|
|
throw 1.1;
|
|
}
|
|
} catch(double &) {
|
|
}
|
|
}
|
|
|
|
void catch_nested_try() noexcept {
|
|
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'catch_nested_try' which should not throw exceptions
|
|
try {
|
|
throw 1;
|
|
} catch(int &) {
|
|
try {
|
|
throw 1;
|
|
} catch(int &) {
|
|
}
|
|
}
|
|
}
|
|
|
|
void bad_catch_nested_try() noexcept {
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'bad_catch_nested_try' which should not throw exceptions
|
|
try {
|
|
throw 1;
|
|
} catch(int &) {
|
|
try {
|
|
throw 1.1;
|
|
} catch(int &) {
|
|
}
|
|
} catch(double &) {
|
|
}
|
|
}
|
|
|
|
void implicit_int_thrower() {
|
|
throw 1;
|
|
}
|
|
|
|
void explicit_int_thrower() throw(int);
|
|
|
|
void indirect_implicit() noexcept {
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'indirect_implicit' which should not throw exceptions
|
|
implicit_int_thrower();
|
|
}
|
|
|
|
void indirect_explicit() noexcept {
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'indirect_explicit' which should not throw exceptions
|
|
explicit_int_thrower();
|
|
}
|
|
|
|
void indirect_catch() noexcept {
|
|
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'indirect_catch' which should not throw exceptions
|
|
try {
|
|
implicit_int_thrower();
|
|
} catch(int&) {
|
|
}
|
|
}
|
|
|
|
template<typename T>
|
|
void dependent_throw() noexcept(sizeof(T)<4) {
|
|
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'dependent_throw' which should not throw exceptions
|
|
if (sizeof(T) > 4)
|
|
throw 1;
|
|
}
|
|
|
|
void swap(int&, int&) {
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'swap' which should not throw exceptions
|
|
throw 1;
|
|
}
|
|
|
|
namespace std {
|
|
class bad_alloc {};
|
|
}
|
|
|
|
void alloc() {
|
|
throw std::bad_alloc();
|
|
}
|
|
|
|
void allocator() noexcept {
|
|
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'allocator' which should not throw exceptions
|
|
alloc();
|
|
}
|
|
|
|
void enabled1() {
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'enabled1' which should not throw exceptions
|
|
throw 1;
|
|
}
|
|
|
|
void enabled2() {
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'enabled2' which should not throw exceptions
|
|
enabled1();
|
|
}
|
|
|
|
void enabled3() {
|
|
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'enabled3' which should not throw exceptions
|
|
try {
|
|
enabled1();
|
|
} catch(...) {
|
|
}
|
|
}
|
|
|
|
class ignored1 {};
|
|
class ignored2 {};
|
|
|
|
void this_does_not_count() noexcept {
|
|
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'this_does_not_count' which should not throw exceptions
|
|
throw ignored1();
|
|
}
|
|
|
|
void this_does_not_count_either(int n) noexcept {
|
|
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'this_does_not_count_either' which should not throw exceptions
|
|
try {
|
|
throw 1;
|
|
if (n) throw ignored2();
|
|
} catch(int &) {
|
|
}
|
|
}
|
|
|
|
void this_counts(int n) noexcept {
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'this_counts' which should not throw exceptions
|
|
if (n) throw 1;
|
|
throw ignored1();
|
|
}
|
|
|
|
void thrower(int n) {
|
|
throw n;
|
|
}
|
|
|
|
int directly_recursive(int n) noexcept {
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'directly_recursive' which should not throw exceptions
|
|
if (n == 0)
|
|
thrower(n);
|
|
return directly_recursive(n);
|
|
}
|
|
|
|
int indirectly_recursive(int n) noexcept;
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'indirectly_recursive' which should not throw exceptions
|
|
|
|
int recursion_helper(int n) {
|
|
indirectly_recursive(n);
|
|
}
|
|
|
|
int indirectly_recursive(int n) noexcept {
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'indirectly_recursive' which should not throw exceptions
|
|
if (n == 0)
|
|
thrower(n);
|
|
return recursion_helper(n);
|
|
}
|
|
|
|
int main() {
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'main' which should not throw exceptions
|
|
throw 1;
|
|
return 0;
|
|
}
|