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. |
3 | namespace std { |
4 | typedef __typeof__(sizeof(0)) size_t; |
5 | enum class align_val_t : std::size_t {}; |
6 | class exception {}; |
7 | class bad_alloc : public exception {}; |
8 | class bad_array_new_length : public bad_alloc {}; |
9 | struct nothrow_t {}; |
10 | extern const nothrow_t nothrow; |
11 | } // namespace std |
12 | |
13 | void *operator new(std::size_t, const std::nothrow_t &) noexcept; |
14 | void *operator new(std::size_t, std::align_val_t, const std::nothrow_t &) noexcept; |
15 | void *operator new(std::size_t, void *) noexcept; |
16 | |
17 | class A {}; |
18 | typedef std::bad_alloc badalloc1; |
19 | using badalloc2 = std::bad_alloc; |
20 | using badalloc3 = std::bad_alloc &; |
21 | |
22 | void *operator new(std::size_t, int, int); |
23 | void *operator new(std::size_t, int, int, int) noexcept; |
24 | |
25 | struct 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 | |
32 | void 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 | |
92 | void 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 | |
116 | void 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 | |
121 | void f_new_placement() noexcept { |
122 | char buf[100]; |
123 | int *I = new (buf) int; |
124 | } |
125 | |
126 | void 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 | |
132 | void 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 | |
142 | void f_est_none() { |
143 | int *I = new int; |
144 | } |
145 | |
146 | void f_est_noexcept_false() noexcept(false) { |
147 | int *I = new int; |
148 | } |
149 | |
150 | void 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 | |
155 | void 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 | |
160 | void f_est_dynamic_1() throw(std::bad_alloc) { |
161 | int *I = new int; |
162 | } |
163 | |
164 | void f_est_dynamic_2() throw(A) { |
165 | // the exception specification list is not checked |
166 | int *I = new int; |
167 | } |
168 | |
169 | void f_try() noexcept try { |
170 | int *I = new int; |
171 | } catch (const std::bad_alloc &) { |
172 | } |
173 | |
174 | void 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 | |
180 | void 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 | |
190 | template <bool P> |
191 | void f_est_noexcept_dependent_unused() noexcept(P) { |
192 | int *I = new int; |
193 | } |
194 | |
195 | template <bool P> |
196 | void 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 | |
201 | template <class T> |
202 | void f_dependent_new() { |
203 | T *X = new T; |
204 | } |
205 | |
206 | void f_1() { |
207 | f_est_noexcept_dependent_used<true>(); |
208 | } |
209 | |