189a1d03eSRichard // RUN: %check_clang_tidy -std=c++14 %s bugprone-unhandled-exception-at-new %t -- -- -fexceptions
2*b4d9ac8bSUtkarsh Saxena // FIXME: Fix the checker to work in C++17 or later mode.
389a1d03eSRichard namespace std {
489a1d03eSRichard typedef __typeof__(sizeof(0)) size_t;
589a1d03eSRichard enum class align_val_t : std::size_t {};
689a1d03eSRichard class exception {};
789a1d03eSRichard class bad_alloc : public exception {};
889a1d03eSRichard class bad_array_new_length : public bad_alloc {};
989a1d03eSRichard struct nothrow_t {};
1089a1d03eSRichard extern const nothrow_t nothrow;
1189a1d03eSRichard } // namespace std
1289a1d03eSRichard
1389a1d03eSRichard void *operator new(std::size_t, const std::nothrow_t &) noexcept;
1489a1d03eSRichard void *operator new(std::size_t, std::align_val_t, const std::nothrow_t &) noexcept;
1589a1d03eSRichard void *operator new(std::size_t, void *) noexcept;
1689a1d03eSRichard
1789a1d03eSRichard class A {};
1889a1d03eSRichard typedef std::bad_alloc badalloc1;
1989a1d03eSRichard using badalloc2 = std::bad_alloc;
2089a1d03eSRichard using badalloc3 = std::bad_alloc &;
2189a1d03eSRichard
2289a1d03eSRichard void *operator new(std::size_t, int, int);
2389a1d03eSRichard void *operator new(std::size_t, int, int, int) noexcept;
2489a1d03eSRichard
2589a1d03eSRichard struct ClassSpecificNew {
2689a1d03eSRichard void *operator new(std::size_t);
2789a1d03eSRichard void *operator new(std::size_t, std::align_val_t);
2889a1d03eSRichard void *operator new(std::size_t, int, int) noexcept;
2989a1d03eSRichard void *operator new(std::size_t, int, int, int);
3089a1d03eSRichard };
3189a1d03eSRichard
f1()3289a1d03eSRichard void f1() noexcept {
3389a1d03eSRichard int *I1 = new int;
3489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: missing exception handler for allocation failure at 'new'
3589a1d03eSRichard try {
3689a1d03eSRichard int *I2 = new int;
3789a1d03eSRichard try {
3889a1d03eSRichard int *I3 = new int;
3989a1d03eSRichard } catch (A) {
4089a1d03eSRichard }
4189a1d03eSRichard } catch (std::bad_alloc) {
4289a1d03eSRichard }
4389a1d03eSRichard
4489a1d03eSRichard try {
4589a1d03eSRichard int *I = new int;
4689a1d03eSRichard } catch (std::bad_alloc &) {
4789a1d03eSRichard }
4889a1d03eSRichard
4989a1d03eSRichard try {
5089a1d03eSRichard int *I = new int;
5189a1d03eSRichard } catch (const std::bad_alloc &) {
5289a1d03eSRichard }
5389a1d03eSRichard
5489a1d03eSRichard try {
5589a1d03eSRichard int *I = new int;
5689a1d03eSRichard } catch (badalloc1) {
5789a1d03eSRichard }
5889a1d03eSRichard
5989a1d03eSRichard try {
6089a1d03eSRichard int *I = new int;
6189a1d03eSRichard } catch (badalloc1 &) {
6289a1d03eSRichard }
6389a1d03eSRichard
6489a1d03eSRichard try {
6589a1d03eSRichard int *I = new int;
6689a1d03eSRichard } catch (const badalloc1 &) {
6789a1d03eSRichard }
6889a1d03eSRichard
6989a1d03eSRichard try {
7089a1d03eSRichard int *I = new int;
7189a1d03eSRichard } catch (badalloc2) {
7289a1d03eSRichard }
7389a1d03eSRichard
7489a1d03eSRichard try {
7589a1d03eSRichard int *I = new int;
7689a1d03eSRichard } catch (badalloc3) {
7789a1d03eSRichard }
7889a1d03eSRichard
7989a1d03eSRichard try {
8089a1d03eSRichard int *I = new int;
8189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: missing exception handler for allocation failure at 'new'
8289a1d03eSRichard } catch (std::bad_alloc *) {
8389a1d03eSRichard }
8489a1d03eSRichard
8589a1d03eSRichard try {
8689a1d03eSRichard int *I = new int;
8789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: missing exception handler for allocation failure at 'new'
8889a1d03eSRichard } catch (A) {
8989a1d03eSRichard }
9089a1d03eSRichard }
9189a1d03eSRichard
f2()9289a1d03eSRichard void f2() noexcept {
9389a1d03eSRichard try {
9489a1d03eSRichard int *I = new int;
9589a1d03eSRichard } catch (A) {
9689a1d03eSRichard } catch (std::bad_alloc) {
9789a1d03eSRichard }
9889a1d03eSRichard
9989a1d03eSRichard try {
10089a1d03eSRichard int *I = new int;
10189a1d03eSRichard } catch (...) {
10289a1d03eSRichard }
10389a1d03eSRichard
10489a1d03eSRichard try {
10589a1d03eSRichard int *I = new int;
10689a1d03eSRichard } catch (const std::exception &) {
10789a1d03eSRichard }
10889a1d03eSRichard
10989a1d03eSRichard try {
11089a1d03eSRichard int *I = new int;
11189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: missing exception handler for allocation failure at 'new'
11289a1d03eSRichard } catch (const std::bad_array_new_length &) {
11389a1d03eSRichard }
11489a1d03eSRichard }
11589a1d03eSRichard
f_new_nothrow()11689a1d03eSRichard void f_new_nothrow() noexcept {
11789a1d03eSRichard int *I1 = new (std::nothrow) int;
11889a1d03eSRichard int *I2 = new (static_cast<std::align_val_t>(1), std::nothrow) int;
11989a1d03eSRichard }
12089a1d03eSRichard
f_new_placement()12189a1d03eSRichard void f_new_placement() noexcept {
12289a1d03eSRichard char buf[100];
12389a1d03eSRichard int *I = new (buf) int;
12489a1d03eSRichard }
12589a1d03eSRichard
f_new_user_defined()12689a1d03eSRichard void f_new_user_defined() noexcept {
12789a1d03eSRichard int *I1 = new (1, 2) int;
12889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: missing exception handler for allocation failure at 'new'
12989a1d03eSRichard int *I2 = new (1, 2, 3) int;
13089a1d03eSRichard }
13189a1d03eSRichard
f_class_specific()13289a1d03eSRichard void f_class_specific() noexcept {
13389a1d03eSRichard ClassSpecificNew *N1 = new ClassSpecificNew;
13489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: missing exception handler for allocation failure at 'new'
13589a1d03eSRichard ClassSpecificNew *N2 = new (static_cast<std::align_val_t>(1)) ClassSpecificNew;
13689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: missing exception handler for allocation failure at 'new'
13789a1d03eSRichard ClassSpecificNew *N3 = new (1, 2) ClassSpecificNew;
13889a1d03eSRichard ClassSpecificNew *N4 = new (1, 2, 3) ClassSpecificNew;
13989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: missing exception handler for allocation failure at 'new'
14089a1d03eSRichard }
14189a1d03eSRichard
f_est_none()14289a1d03eSRichard void f_est_none() {
14389a1d03eSRichard int *I = new int;
14489a1d03eSRichard }
14589a1d03eSRichard
f_est_noexcept_false()14689a1d03eSRichard void f_est_noexcept_false() noexcept(false) {
14789a1d03eSRichard int *I = new int;
14889a1d03eSRichard }
14989a1d03eSRichard
f_est_noexcept_true()15089a1d03eSRichard void f_est_noexcept_true() noexcept(true) {
15189a1d03eSRichard int *I = new int;
15289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: missing exception handler for allocation failure at 'new'
15389a1d03eSRichard }
15489a1d03eSRichard
f_est_dynamic_none()15589a1d03eSRichard void f_est_dynamic_none() throw() {
15689a1d03eSRichard int *I = new int;
15789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: missing exception handler for allocation failure at 'new'
15889a1d03eSRichard }
15989a1d03eSRichard
f_est_dynamic_1()16089a1d03eSRichard void f_est_dynamic_1() throw(std::bad_alloc) {
16189a1d03eSRichard int *I = new int;
16289a1d03eSRichard }
16389a1d03eSRichard
f_est_dynamic_2()16489a1d03eSRichard void f_est_dynamic_2() throw(A) {
16589a1d03eSRichard // the exception specification list is not checked
16689a1d03eSRichard int *I = new int;
16789a1d03eSRichard }
16889a1d03eSRichard
f_try()16989a1d03eSRichard void f_try() noexcept try {
17089a1d03eSRichard int *I = new int;
17189a1d03eSRichard } catch (const std::bad_alloc &) {
17289a1d03eSRichard }
17389a1d03eSRichard
f_try_bad()17489a1d03eSRichard void f_try_bad() noexcept try {
17589a1d03eSRichard int *I = new int;
17689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: missing exception handler for allocation failure at 'new'
17789a1d03eSRichard } catch (const A &) {
17889a1d03eSRichard }
17989a1d03eSRichard
f_embedded_try()18089a1d03eSRichard void f_embedded_try() noexcept {
18189a1d03eSRichard try {
18289a1d03eSRichard try {
18389a1d03eSRichard int *I = new int;
18489a1d03eSRichard } catch (const A &) {
18589a1d03eSRichard }
18689a1d03eSRichard } catch (const std::bad_alloc &) {
18789a1d03eSRichard }
18889a1d03eSRichard }
18989a1d03eSRichard
19089a1d03eSRichard template <bool P>
f_est_noexcept_dependent_unused()19189a1d03eSRichard void f_est_noexcept_dependent_unused() noexcept(P) {
19289a1d03eSRichard int *I = new int;
19389a1d03eSRichard }
19489a1d03eSRichard
19589a1d03eSRichard template <bool P>
f_est_noexcept_dependent_used()19689a1d03eSRichard void f_est_noexcept_dependent_used() noexcept(P) {
19789a1d03eSRichard int *I = new int;
19889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: missing exception handler for allocation failure at 'new'
19989a1d03eSRichard }
20089a1d03eSRichard
20189a1d03eSRichard template <class T>
f_dependent_new()20289a1d03eSRichard void f_dependent_new() {
20389a1d03eSRichard T *X = new T;
20489a1d03eSRichard }
20589a1d03eSRichard
f_1()20689a1d03eSRichard void f_1() {
20789a1d03eSRichard f_est_noexcept_dependent_used<true>();
20889a1d03eSRichard }
209