]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/18_support/new_nothrow.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 18_support / new_nothrow.cc
1 // Copyright (C) 2018-2020 Free Software Foundation, Inc.
2 //
3 // This file is part of the GNU ISO C++ Library. This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 3, or (at your option)
7 // any later version.
8
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING3. If not see
16 // <http://www.gnu.org/licenses/>.
17
18 // { dg-do run }
19 // { dg-xfail-run-if "AIX operator new" { powerpc-ibm-aix* } }
20
21 #include <new>
22 #include <stdlib.h>
23 #include <testsuite_hooks.h>
24
25 // PR libstdc++/68210
26
27 struct MyBadAlloc: std::bad_alloc { };
28
29 static bool new_fail;
30 static bool bad_alloc_thrown;
31 static unsigned new_called;
32 static unsigned delete_called;
33 static unsigned new_vec_called;
34 static unsigned delete_vec_called;
35 static unsigned new_handler_called;
36
37 static void new_handler ()
38 {
39 if (new_handler_called++)
40 throw MyBadAlloc ();
41 }
42
43 void* operator new (size_t n)
44 {
45 static size_t cntr;
46
47 ++new_called;
48
49 for ( ; ; ) {
50 if (void *p = new_fail ? 0 : malloc (n + sizeof n)) {
51 *static_cast<size_t*>(p) = ++cntr;
52 return static_cast<size_t*>(p) + 1;
53 }
54
55 if (std::new_handler h = std::set_new_handler (0)) {
56 std::set_new_handler (h);
57 h ();
58 }
59 else {
60 bad_alloc_thrown = true;
61 throw MyBadAlloc ();
62 }
63 }
64 }
65
66 void operator delete (void *p)
67 {
68 ++delete_called;
69 if (p)
70 free (static_cast<size_t*>(p) - 1);
71 }
72
73 void* operator new[] (size_t n)
74 {
75 ++new_vec_called;
76 return operator new(n);
77 }
78
79 void operator delete[] (void *p)
80 {
81 ++delete_vec_called;
82 operator delete(p);
83 }
84
85 #if __cplusplus >= 201402L
86 void operator delete (void *p, std::size_t)
87 {
88 ::operator delete(p);
89 }
90 void operator delete[] (void *p, std::size_t)
91 {
92 ::operator delete[](p);
93 }
94 #endif
95
96 void init()
97 {
98 new_fail = false;
99 new_called = 0;
100 delete_called = 0;
101 new_vec_called = 0;
102 delete_vec_called = 0;
103 new_handler_called = 0;
104 std::set_new_handler (0);
105 }
106
107 void
108 test01()
109 {
110 init ();
111
112 void *p = operator new (1, std::nothrow);
113
114 VERIFY (p != 0);
115 VERIFY (1 == new_called);
116 VERIFY (0 == new_handler_called);
117 VERIFY (!bad_alloc_thrown);
118
119 operator delete (p, std::nothrow);
120 VERIFY( 1 == delete_called );
121
122 new_fail = true;
123 p = operator new (1, std::nothrow);
124
125 VERIFY (0 == p);
126 VERIFY (2 == new_called);
127 VERIFY (0 == new_handler_called);
128 VERIFY (bad_alloc_thrown);
129
130 new_fail = true;
131 bad_alloc_thrown = false;
132 std::set_new_handler (new_handler);
133 p = operator new (1, std::nothrow);
134
135 VERIFY (0 == p);
136 VERIFY (3 == new_called);
137 VERIFY (2 == new_handler_called);
138 VERIFY (!bad_alloc_thrown);
139 }
140
141 void
142 test02()
143 {
144 init ();
145
146 void *p = operator new[] (1, std::nothrow);
147
148 VERIFY (p != 0);
149 VERIFY (1 == new_called);
150 VERIFY (1 == new_vec_called);
151 VERIFY (0 == new_handler_called);
152 VERIFY (!bad_alloc_thrown);
153
154 operator delete[] (p, std::nothrow);
155 VERIFY( 1 == delete_called );
156 VERIFY( 1 == delete_vec_called );
157
158 new_fail = true;
159 p = operator new[] (1, std::nothrow);
160
161 VERIFY (0 == p);
162 VERIFY (2 == new_called);
163 VERIFY (2 == new_vec_called);
164 VERIFY (0 == new_handler_called);
165 VERIFY (bad_alloc_thrown);
166
167 new_fail = true;
168 bad_alloc_thrown = false;
169 std::set_new_handler (new_handler);
170 p = operator new[] (1, std::nothrow);
171
172 VERIFY (0 == p);
173 VERIFY (3 == new_called);
174 VERIFY (3 == new_vec_called);
175 VERIFY (2 == new_handler_called);
176 VERIFY (!bad_alloc_thrown);
177 }
178
179
180 int main()
181 {
182 test01();
183 test02();
184 }