1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
// 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) {}
void funcCallWithTempExcTest() {
f(5, RegularException());
}
// Global variable initialization test.
RegularException exc = RegularException();
RegularException *excptr = new RegularException();
void localVariableInitTest() {
RegularException exc = RegularException();
RegularException *excptr = new RegularException();
}
class CtorInitializerListTest {
RegularException exc;
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;
}
|