62 fail = line = __LINE__; \
63 signal (SIGABRT, handle_ABRT); \
64 if (0 == setjmp (env)) { \
67 rw_assert (0, __FILE__, line, "expected assertion"); \
73 fail = -1; line = __LINE__; \
74 signal (SIGABRT, handle_ABRT); \
75 if (0 == setjmp (env)) { \
78 else if (fail != line) { \
80 rw_assert (0, __FILE__, line, "unexpected assertion"); \
88 "exercising successful allocation and deallocation");
92 PASS (
p =
operator new (0));
93 rw_assert (
p != 0, __FILE__, __LINE__,
"operator new(0) != 0");
99 PASS (
p =
operator new (1));
100 rw_assert (
p != 0, __FILE__, __LINE__,
"operator new(1) != 0");
106 PASS (
p =
operator new (2));
107 rw_assert (
p != 0, __FILE__, __LINE__,
"operator new(2) != 0");
113 PASS (
p =
operator new (1024));
114 rw_assert (
p != 0, __FILE__, __LINE__,
"operator new(1024) != 0");
122 try { code; fail = 1; } \
123 catch (_RWSTD_BAD_ALLOC) { fail = 0; } \
124 catch (...) { fail = 2; } \
125 rw_assert (!fail, __FILE__, __LINE__, \
126 "%s", 1 == fail ? "failed to throw" : \
127 "threw an unknown exception")
129#define NOTHROW(code) \
130 try { fail = 0; code; } \
131 catch (...) { fail = 1; } \
132 rw_assert (!fail, __FILE__, __LINE__, \
133 "unexpected exception")
137 rw_info (0, __FILE__, __LINE__,
138 "exercising the ability of ordinary "
139 "operator new to throw std::bad_alloc");
145 CATCH (
operator new (0));
146 CATCH (
operator new (1));
147 CATCH (
operator new (2));
148 CATCH (
operator new (1024));
153 operator delete[](
p);
159 operator delete[](
p);
165 operator delete[](
p);
171 operator delete[](
p);
174 rw_info (0, __FILE__, __LINE__,
175 "exercising the ability of the array form "
176 "of operator new to throw std::bad_alloc");
181 CATCH (
operator new[](0));
182 CATCH (
operator new[](1));
183 CATCH (
operator new[](2));
184 CATCH (
operator new[](1024));
189 rw_assert (
p != 0, __FILE__, __LINE__,
"operator new[](0) != 0");
196 rw_assert (
p != 0, __FILE__, __LINE__,
"operator new[](1) != 0");
203 rw_assert (
p != 0, __FILE__, __LINE__,
"operator new[](32) != 0");
210 rw_assert (
p != 0, __FILE__, __LINE__,
"operator new[](4096) != 0");
221 rw_info (0, __FILE__, __LINE__,
222 "exercising the ability to detect "
223 "allocation/deallocation mismatches");
229 PASS (
p =
operator new (0));
230 FAIL (
operator delete[](
p));
231 PASS (
operator delete (
p));
236 PASS (
p =
operator new (1));
237 FAIL (
operator delete[](
p));
238 PASS (
operator delete (
p));
243 PASS (
p =
operator new[](33));
244 FAIL (
operator delete (
p));
245 PASS (
operator delete[] (
p));
253 rw_info (0, __FILE__, __LINE__,
254 "exercising the ability to detect "
255 "deletion of unallocated storage");
261 FAIL (
delete (
p - 1));
262 FAIL (
delete (
p + 1));
269 PASS (
p =
new char [4]);
271 FAIL (
delete (
p - 1));
272 FAIL (
delete (
p + 1));
273 FAIL (
delete (
p + 2));
274 FAIL (
delete (
p + 3));
275 FAIL (
delete (
p + 4));
277 FAIL (
delete[] (
p - 1));
278 FAIL (
delete[] (
p + 1));
279 FAIL (
delete[] (
p + 2));
280 FAIL (
delete[] (
p + 3));
281 FAIL (
delete[] (
p + 4));
291 rw_info (0, __FILE__, __LINE__,
292 "exercising the ability to detect double deletion");
304 PASS (
p =
new char [32]);
316 rw_info (0, __FILE__, __LINE__,
317 "exercising the ability to detect memory corruption");
320 for (std::size_t
i = 1;
i != 8; ++
i) {
343#define LEAK(code, bytes, blks) \
346 rwt_check_leaks (0, 0); \
351 std::size_t nbytes; \
352 const std::size_t nblocks = rwt_check_leaks (&nbytes, 0); \
354 rw_assert (blks == nblocks && bytes == nbytes, \
355 __FILE__, __LINE__, \
356 "failed to detect a leak of %d bytes in " \
357 "%d blocks: got %zu bytes in %zu blocks", \
358 bytes, blks, nbytes, nblocks); \
364 rw_info (0, __FILE__, __LINE__,
365 "exercising the ability to detect memory leaks");
369 LEAK (
p =
operator new (0), 0, 1);
370 PASS (
operator delete (
p));
375 LEAK (
p =
operator new (1), 1, 1);
376 PASS (
operator delete (
p));
381 LEAK (
p =
operator new (1234), 1234, 1);
382 PASS (
operator delete (
p));
388 LEAK (p0 =
operator new (32);
389 p1 =
operator new (64), 96, 2);
390 PASS (
operator delete (p0));
391 PASS (
operator delete (
p1));
396 LEAK (
p =
operator new[] (12345), 12345, 1);
397 PASS (
operator delete[] (
p));
405 rw_info (0, __FILE__, __LINE__,
406 "stress-testing replacement operators new and delete");
415 const std::size_t
N =
sizeof ptrs /
sizeof *ptrs;
417 for (std::size_t
i = 0;
i !=
N; ++
i) {
419 PASS (ptrs [
i] =
operator new[](
i));
422 PASS (ptrs [
i] =
operator new (
i));
426 for (std::size_t
i = 0;
i <
N; ++
i) {
428 const std::size_t
j = (
i * (
i + 17)) %
N;
431 PASS (
operator delete[](ptrs [
j]));
434 PASS (
operator delete (ptrs [
j]));
440 for (std::size_t
i = 0;
i <
N; ++
i) {
442 PASS (
operator delete[](ptrs [
i]));
445 PASS (
operator delete (ptrs [
i]));
452 rw_assert (0 == nblocks && 0 == nbytes, __FILE__, __LINE__,
453 "false leaks detected: %zu bytes in %zu blocks",
459static int rw_opt_no_new_delete;
460static int rw_opt_no_bad_alloc;
461static int rw_opt_no_mismatch;
462static int rw_opt_no_bad_delete;
463static int rw_opt_no_double_delete;
464static int rw_opt_no_corruption;
465static int rw_opt_no_leaks;
466static int rw_opt_no_stress;
470#ifndef _RWSTD_NO_REPLACEABLE_NEW_DELETE
478 if (rw_opt_no_ ## name) \
479 rw_note (0, 0, __LINE__, "%s test disabled", #name); \
485 TEST (double_delete);
493 rw_note (0, 0, __LINE__,
"Test disabled");
502int main (
int argc,
char** argv)
504 return rw_test (argc, argv, __FILE__,
512 "|-no-double-delete# "
516 &rw_opt_no_new_delete,
517 &rw_opt_no_bad_alloc,
519 &rw_opt_no_bad_delete,
520 &rw_opt_no_double_delete,
521 &rw_opt_no_corruption,
#define LEAK(code, bytes, blks)
int run_test(int, char **)
void test_double_delete()
_TEST_EXPORT int rw_test(int argc, char *argv[], const char *filename, const char *clause, const char *comment, int(*testfun)(int, char **), const char *optspec,...)
_TEST_EXPORT bool rw_enable(int(*fun)(int, const char *, int, const char *,...), bool enable=true)
_TEST_EXPORT int rw_info(int, const char *, int, const char *,...)
_TEST_EXPORT int rw_note(int, const char *, int, const char *,...)
_TEST_EXPORT int rw_assert(int, const char *, int, const char *,...)
_TEST_EXPORT int rw_error(int, const char *, int, const char *,...)
_TEST_EXPORT rwt_free_store * rwt_get_free_store(rwt_free_store *)
_RWSTD_SIZE_T * throw_at_blocks_[2]