forked from OSchip/llvm-project
189 lines
4.4 KiB
C++
189 lines
4.4 KiB
C++
// RUN: %check_clang_tidy %s bugprone-throw-keyword-missing %t -- -- -fexceptions
|
|
|
|
namespace std {
|
|
|
|
// std::string declaration (taken from test/clang-tidy/readability-redundant-string-cstr-msvc.cpp).
|
|
template <typename T>
|
|
class allocator {};
|
|
template <typename T>
|
|
class char_traits {};
|
|
template <typename C, typename T = std::char_traits<C>, typename A = std::allocator<C>>
|
|
struct basic_string {
|
|
basic_string();
|
|
basic_string(const basic_string &);
|
|
// MSVC headers define two constructors instead of using optional arguments.
|
|
basic_string(const C *);
|
|
basic_string(const C *, const A &);
|
|
~basic_string();
|
|
};
|
|
typedef basic_string<char> string;
|
|
typedef basic_string<wchar_t> wstring;
|
|
|
|
// std::exception and std::runtime_error declaration.
|
|
struct exception {
|
|
exception();
|
|
exception(const exception &other);
|
|
virtual ~exception();
|
|
};
|
|
|
|
struct runtime_error : public exception {
|
|
explicit runtime_error(const std::string &what_arg);
|
|
};
|
|
|
|
} // namespace std
|
|
|
|
// The usage of this class should never emit a warning.
|
|
struct RegularClass {};
|
|
|
|
// Class name contains the substring "exception", in certain cases using this class should emit a warning.
|
|
struct RegularException {
|
|
RegularException() {}
|
|
|
|
// Constructors with a single argument are treated differently (cxxFunctionalCastExpr).
|
|
RegularException(int) {}
|
|
};
|
|
|
|
// --------------
|
|
|
|
void stdExceptionNotTrownTest(int i) {
|
|
if (i < 0)
|
|
// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception object created but not thrown; did you mean 'throw {{.*}}'? [bugprone-throw-keyword-missing]
|
|
std::exception();
|
|
|
|
if (i > 0)
|
|
// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception
|
|
std::runtime_error("Unexpected argument");
|
|
}
|
|
|
|
void stdExceptionThrownTest(int i) {
|
|
if (i < 0)
|
|
throw std::exception();
|
|
|
|
if (i > 0)
|
|
throw std::runtime_error("Unexpected argument");
|
|
}
|
|
|
|
void regularClassNotThrownTest(int i) {
|
|
if (i < 0)
|
|
RegularClass();
|
|
}
|
|
|
|
void regularClassThrownTest(int i) {
|
|
if (i < 0)
|
|
throw RegularClass();
|
|
}
|
|
|
|
void nameContainsExceptionNotThrownTest(int i) {
|
|
if (i < 0)
|
|
// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception
|
|
RegularException();
|
|
|
|
if (i > 0)
|
|
// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception
|
|
RegularException(5);
|
|
}
|
|
|
|
void nameContainsExceptionThrownTest(int i) {
|
|
if (i < 0)
|
|
throw RegularException();
|
|
|
|
if (i > 0)
|
|
throw RegularException(5);
|
|
}
|
|
|
|
template <class Exception>
|
|
void f(int i, Exception excToBeThrown) {}
|
|
|
|
template <class SomeType>
|
|
void templ(int i) {
|
|
if (i > 0)
|
|
SomeType();
|
|
}
|
|
|
|
void funcCallWithTempExcTest() {
|
|
f(5, RegularException());
|
|
|
|
templ<RegularException>(4);
|
|
templ<RegularClass>(4);
|
|
}
|
|
|
|
// Global variable initialization test.
|
|
RegularException exc = RegularException();
|
|
RegularException *excptr = new RegularException();
|
|
|
|
void localVariableInitTest() {
|
|
RegularException exc = RegularException();
|
|
RegularException *excptr = new RegularException();
|
|
}
|
|
|
|
class CtorInitializerListTest {
|
|
RegularException exc;
|
|
RegularException exc2{};
|
|
|
|
CtorInitializerListTest() : exc(RegularException()) {}
|
|
|
|
CtorInitializerListTest(int) try : exc(RegularException()) {
|
|
// Constructor body
|
|
} catch (...) {
|
|
// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception
|
|
RegularException();
|
|
}
|
|
|
|
CtorInitializerListTest(float);
|
|
};
|
|
|
|
CtorInitializerListTest::CtorInitializerListTest(float) try : exc(RegularException()) {
|
|
// Constructor body
|
|
} catch (...) {
|
|
// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: suspicious exception
|
|
RegularException();
|
|
}
|
|
|
|
RegularException funcReturningExceptionTest(int i) {
|
|
return RegularException();
|
|
}
|
|
|
|
void returnedValueTest() {
|
|
funcReturningExceptionTest(3);
|
|
}
|
|
|
|
struct ClassBracedInitListTest {
|
|
ClassBracedInitListTest(RegularException exc) {}
|
|
};
|
|
|
|
void foo(RegularException, ClassBracedInitListTest) {}
|
|
|
|
void bracedInitListTest() {
|
|
RegularException exc{};
|
|
ClassBracedInitListTest test = {RegularException()};
|
|
foo({}, {RegularException()});
|
|
}
|
|
|
|
typedef std::exception ERROR_BASE;
|
|
class RegularError : public ERROR_BASE {};
|
|
|
|
void typedefTest() {
|
|
// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: suspicious exception
|
|
RegularError();
|
|
}
|
|
|
|
struct ExceptionRAII {
|
|
ExceptionRAII() {}
|
|
~ExceptionRAII() {}
|
|
};
|
|
|
|
void exceptionRAIITest() {
|
|
ExceptionRAII E;
|
|
}
|
|
|
|
namespace std {
|
|
typedef decltype(sizeof(void*)) size_t;
|
|
}
|
|
|
|
void* operator new(std::size_t, void*);
|
|
|
|
void placeMentNewTest() {
|
|
alignas(RegularException) unsigned char expr[sizeof(RegularException)];
|
|
new (expr) RegularException{};
|
|
}
|