1 // RUN: %check_clang_tidy -std=c++14 %s bugprone-unhandled-exception-at-new %t -- -- -fexceptions
2 
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 
f1()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 
f2()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 
f_new_nothrow()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 
f_new_placement()121 void f_new_placement() noexcept {
122   char buf[100];
123   int *I = new (buf) int;
124 }
125 
f_new_user_defined()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 
f_class_specific()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 
f_est_none()142 void f_est_none() {
143   int *I = new int;
144 }
145 
f_est_noexcept_false()146 void f_est_noexcept_false() noexcept(false) {
147   int *I = new int;
148 }
149 
f_est_noexcept_true()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 
f_est_dynamic_none()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 
f_est_dynamic_1()160 void f_est_dynamic_1() throw(std::bad_alloc) {
161   int *I = new int;
162 }
163 
f_est_dynamic_2()164 void f_est_dynamic_2() throw(A) {
165   // the exception specification list is not checked
166   int *I = new int;
167 }
168 
f_try()169 void f_try() noexcept try {
170   int *I = new int;
171 } catch (const std::bad_alloc &) {
172 }
173 
f_try_bad()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 
f_embedded_try()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>
f_est_noexcept_dependent_unused()191 void f_est_noexcept_dependent_unused() noexcept(P) {
192   int *I = new int;
193 }
194 
195 template <bool P>
f_est_noexcept_dependent_used()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>
f_dependent_new()202 void f_dependent_new() {
203   T *X = new T;
204 }
205 
f_1()206 void f_1() {
207   f_est_noexcept_dependent_used<true>();
208 }
209