1// RUN: %check_clang_tidy -std=c++14 %s bugprone-unhandled-exception-at-new %t -- -- -fexceptions
2// FIXME: Fix the checker to work in C++17 or later mode.
3namespace std {
4typedef __typeof__(sizeof(0)) size_t;
5enum class align_val_t : std::size_t {};
6class exception {};
7class bad_alloc : public exception {};
8class bad_array_new_length : public bad_alloc {};
9struct nothrow_t {};
10extern const nothrow_t nothrow;
11} // namespace std
12
13void *operator new(std::size_t, const std::nothrow_t &) noexcept;
14void *operator new(std::size_t, std::align_val_t, const std::nothrow_t &) noexcept;
15void *operator new(std::size_t, void *) noexcept;
16
17class A {};
18typedef std::bad_alloc badalloc1;
19using badalloc2 = std::bad_alloc;
20using badalloc3 = std::bad_alloc &;
21
22void *operator new(std::size_t, int, int);
23void *operator new(std::size_t, int, int, int) noexcept;
24
25struct ClassSpecificNew {
26 void *operator new(std::size_t);
27 void *operator new(std::size_t, std::align_val_t);
28 void *operator new(std::size_t, int, int) noexcept;
29 void *operator new(std::size_t, int, int, int);
30};
31
32void f1() noexcept {
33 int *I1 = new int;
34 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: missing exception handler for allocation failure at 'new'
35 try {
36 int *I2 = new int;
37 try {
38 int *I3 = new int;
39 } catch (A) {
40 }
41 } catch (std::bad_alloc) {
42 }
43
44 try {
45 int *I = new int;
46 } catch (std::bad_alloc &) {
47 }
48
49 try {
50 int *I = new int;
51 } catch (const std::bad_alloc &) {
52 }
53
54 try {
55 int *I = new int;
56 } catch (badalloc1) {
57 }
58
59 try {
60 int *I = new int;
61 } catch (badalloc1 &) {
62 }
63
64 try {
65 int *I = new int;
66 } catch (const badalloc1 &) {
67 }
68
69 try {
70 int *I = new int;
71 } catch (badalloc2) {
72 }
73
74 try {
75 int *I = new int;
76 } catch (badalloc3) {
77 }
78
79 try {
80 int *I = new int;
81 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: missing exception handler for allocation failure at 'new'
82 } catch (std::bad_alloc *) {
83 }
84
85 try {
86 int *I = new int;
87 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: missing exception handler for allocation failure at 'new'
88 } catch (A) {
89 }
90}
91
92void f2() noexcept {
93 try {
94 int *I = new int;
95 } catch (A) {
96 } catch (std::bad_alloc) {
97 }
98
99 try {
100 int *I = new int;
101 } catch (...) {
102 }
103
104 try {
105 int *I = new int;
106 } catch (const std::exception &) {
107 }
108
109 try {
110 int *I = new int;
111 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: missing exception handler for allocation failure at 'new'
112 } catch (const std::bad_array_new_length &) {
113 }
114}
115
116void f_new_nothrow() noexcept {
117 int *I1 = new (std::nothrow) int;
118 int *I2 = new (static_cast<std::align_val_t>(1), std::nothrow) int;
119}
120
121void f_new_placement() noexcept {
122 char buf[100];
123 int *I = new (buf) int;
124}
125
126void f_new_user_defined() noexcept {
127 int *I1 = new (1, 2) int;
128 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: missing exception handler for allocation failure at 'new'
129 int *I2 = new (1, 2, 3) int;
130}
131
132void f_class_specific() noexcept {
133 ClassSpecificNew *N1 = new ClassSpecificNew;
134 // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: missing exception handler for allocation failure at 'new'
135 ClassSpecificNew *N2 = new (static_cast<std::align_val_t>(1)) ClassSpecificNew;
136 // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: missing exception handler for allocation failure at 'new'
137 ClassSpecificNew *N3 = new (1, 2) ClassSpecificNew;
138 ClassSpecificNew *N4 = new (1, 2, 3) ClassSpecificNew;
139 // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: missing exception handler for allocation failure at 'new'
140}
141
142void f_est_none() {
143 int *I = new int;
144}
145
146void f_est_noexcept_false() noexcept(false) {
147 int *I = new int;
148}
149
150void f_est_noexcept_true() noexcept(true) {
151 int *I = new int;
152 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: missing exception handler for allocation failure at 'new'
153}
154
155void f_est_dynamic_none() throw() {
156 int *I = new int;
157 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: missing exception handler for allocation failure at 'new'
158}
159
160void f_est_dynamic_1() throw(std::bad_alloc) {
161 int *I = new int;
162}
163
164void f_est_dynamic_2() throw(A) {
165 // the exception specification list is not checked
166 int *I = new int;
167}
168
169void f_try() noexcept try {
170 int *I = new int;
171} catch (const std::bad_alloc &) {
172}
173
174void f_try_bad() noexcept try {
175 int *I = new int;
176 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: missing exception handler for allocation failure at 'new'
177} catch (const A &) {
178}
179
180void f_embedded_try() noexcept {
181 try {
182 try {
183 int *I = new int;
184 } catch (const A &) {
185 }
186 } catch (const std::bad_alloc &) {
187 }
188}
189
190template <bool P>
191void f_est_noexcept_dependent_unused() noexcept(P) {
192 int *I = new int;
193}
194
195template <bool P>
196void f_est_noexcept_dependent_used() noexcept(P) {
197 int *I = new int;
198 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: missing exception handler for allocation failure at 'new'
199}
200
201template <class T>
202void f_dependent_new() {
203 T *X = new T;
204}
205
206void f_1() {
207 f_est_noexcept_dependent_used<true>();
208}
209

source code of clang-tools-extra/test/clang-tidy/checkers/bugprone/unhandled-exception-at-new.cpp