1// RUN: %check_clang_tidy %s bugprone-throw-keyword-missing %t -- -- -fexceptions
2
3namespace std {
4
5// std::string declaration (taken from test/clang-tidy/readability-redundant-string-cstr-msvc.cpp).
6template <typename T>
7class allocator {};
8template <typename T>
9class char_traits {};
10template <typename C, typename T = std::char_traits<C>, typename A = std::allocator<C>>
11struct 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};
19typedef basic_string<char> string;
20typedef basic_string<wchar_t> wstring;
21
22// std::exception and std::runtime_error declaration.
23struct exception {
24 exception();
25 exception(const exception &other);
26 virtual ~exception();
27};
28
29struct 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.
36struct RegularClass {};
37
38// Class name contains the substring "exception", in certain cases using this class should emit a warning.
39struct RegularException {
40 RegularException() {}
41
42 // Constructors with a single argument are treated differently (cxxFunctionalCastExpr).
43 RegularException(int) {}
44};
45
46// --------------
47
48void 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
58void 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
66void regularClassNotThrownTest(int i) {
67 if (i < 0)
68 RegularClass();
69}
70
71void regularClassThrownTest(int i) {
72 if (i < 0)
73 throw RegularClass();
74}
75
76void 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
86void nameContainsExceptionThrownTest(int i) {
87 if (i < 0)
88 throw RegularException();
89
90 if (i > 0)
91 throw RegularException(5);
92}
93
94template <class Exception>
95void f(int i, Exception excToBeThrown) {}
96
97template <class SomeType>
98void templ(int i) {
99 if (i > 0)
100 SomeType();
101}
102
103void funcCallWithTempExcTest() {
104 f(i: 5, excToBeThrown: RegularException());
105
106 templ<RegularException>(i: 4);
107 templ<RegularClass>(i: 4);
108}
109
110// Global variable initialization test.
111RegularException exc = RegularException();
112RegularException *excptr = new RegularException();
113
114void localVariableInitTest() {
115 RegularException exc = RegularException();
116 RegularException *excptr = new RegularException();
117}
118
119class 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
135CtorInitializerListTest::CtorInitializerListTest(float) try : exc(RegularException()) {
136 // Constructor body
137} catch (...) {
138 // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: suspicious exception
139 RegularException();
140}
141
142namespace GH115055 {
143class CtorInitializerListTest2 {
144 public:
145 CtorInitializerListTest2() {}
146 private:
147 RegularException exc{};
148};
149} // namespace GH115055
150
151RegularException funcReturningExceptionTest(int i) {
152 return RegularException();
153}
154
155void returnedValueTest() {
156 funcReturningExceptionTest(i: 3);
157}
158
159struct ClassBracedInitListTest {
160 ClassBracedInitListTest(RegularException exc) {}
161};
162
163void foo(RegularException, ClassBracedInitListTest) {}
164
165void bracedInitListTest() {
166 RegularException exc{};
167 ClassBracedInitListTest test = {RegularException()};
168 foo({}, {RegularException()});
169}
170
171typedef std::exception ERROR_BASE;
172class RegularError : public ERROR_BASE {};
173
174void typedefTest() {
175 // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: suspicious exception
176 RegularError();
177}
178
179struct ExceptionRAII {
180 ExceptionRAII() {}
181 ~ExceptionRAII() {}
182};
183
184void exceptionRAIITest() {
185 ExceptionRAII E;
186}
187
188namespace std {
189typedef decltype(sizeof(void*)) size_t;
190}
191
192void* operator new(std::size_t, void*);
193
194void placeMentNewTest() {
195 alignas(RegularException) unsigned char expr[sizeof(RegularException)];
196 new (expr) RegularException{};
197}
198

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of clang-tools-extra/test/clang-tidy/checkers/bugprone/throw-keyword-missing.cpp