diff options
author | Eric Fiselier <eric@efcs.ca> | 2016-10-14 06:46:30 +0000 |
---|---|---|
committer | Eric Fiselier <eric@efcs.ca> | 2016-10-14 06:46:30 +0000 |
commit | 0ae4f23fdcd8a278c58ea3ae2f062220763bcb66 (patch) | |
tree | a56304a3a8407388298099dd5f620cfd9c2b0fa2 /libcxx/test/std/language.support/support.dynamic | |
parent | d2c29f9c54fd7aec1ba1411742d47510a82e3864 (diff) | |
download | bcm5719-llvm-0ae4f23fdcd8a278c58ea3ae2f062220763bcb66.tar.gz bcm5719-llvm-0ae4f23fdcd8a278c58ea3ae2f062220763bcb66.zip |
Implement P0035R4 -- Add C++17 aligned allocation functions
Summary:
This patch implements the library side of P0035R4. The implementation is thanks to @rsmith.
In addition to the C++17 implementation, the library implementation can be explicitly turned on using `-faligned-allocation` in all dialects.
Reviewers: mclow.lists, rsmith
Subscribers: rsmith, cfe-commits
Differential Revision: https://reviews.llvm.org/D25591
llvm-svn: 284206
Diffstat (limited to 'libcxx/test/std/language.support/support.dynamic')
11 files changed, 845 insertions, 0 deletions
diff --git a/libcxx/test/std/language.support/support.dynamic/align_val_t.pass.cpp b/libcxx/test/std/language.support/support.dynamic/align_val_t.pass.cpp new file mode 100644 index 00000000000..0a19de919f7 --- /dev/null +++ b/libcxx/test/std/language.support/support.dynamic/align_val_t.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// enum class align_val_t : size_t {} + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +#include <new> + +#include "test_macros.h" + +int main() { + { + static_assert(std::is_enum<std::align_val_t>::value, ""); + static_assert(std::is_same<std::underlying_type<std::align_val_t>::type, std::size_t>::value, ""); + static_assert(!std::is_constructible<std::align_val_t, std::size_t>::value, ""); + static_assert(!std::is_constructible<std::size_t, std::align_val_t>::value, ""); + } + { + constexpr auto a = std::align_val_t(0); + constexpr auto b = std::align_val_t(32); + constexpr auto c = std::align_val_t(-1); + static_assert(a != b, ""); + static_assert(a == std::align_val_t(0), ""); + static_assert(b == std::align_val_t(32), ""); + static_assert(static_cast<std::size_t>(c) == (std::size_t)-1, ""); + } +}
\ No newline at end of file diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp new file mode 100644 index 00000000000..6d7ef7af6fc --- /dev/null +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp @@ -0,0 +1,83 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// test aligned operator delete replacement. + +// UNSUPPORTED: sanitizer-new-delete, c++98, c++03, c++11, c++14 + +// Older Clang versions do not support this +// XFAIL: clang-3, apple-clang + +// None of the current GCC compilers support this. +// XFAIL: gcc-4, gcc-5, gcc-6 + +#include <new> +#include <cstddef> +#include <cstdlib> +#include <cassert> + +constexpr auto OverAligned = alignof(std::max_align_t) * 2; + +int unsized_delete_called = 0; +int unsized_delete_nothrow_called = 0; +int aligned_delete_called = 0; + +void reset() { + unsized_delete_called = 0; + unsized_delete_nothrow_called = 0; + aligned_delete_called = 0; +} + +void operator delete(void* p) throw() +{ + ++unsized_delete_called; + std::free(p); +} + +void operator delete(void* p, const std::nothrow_t&) throw() +{ + ++unsized_delete_nothrow_called; + std::free(p); +} + +void operator delete [] (void* p, std::align_val_t a) throw() +{ + ++aligned_delete_called; + std::free(p); +} + +struct alignas(OverAligned) A {}; +struct alignas(std::max_align_t) B {}; + +int main() +{ + { + B *x = new B; + assert(0 == unsized_delete_called); + assert(0 == unsized_delete_nothrow_called); + assert(0 == aligned_delete_called); + + delete x; + assert(1 == unsized_delete_called); + assert(0 == unsized_delete_nothrow_called); + assert(0 == aligned_delete_called); + } + reset(); + { + A *x = new A; + assert(0 == unsized_delete_called); + assert(0 == unsized_delete_nothrow_called); + assert(0 == aligned_delete_called); + + delete x; + assert(0 == unsized_delete_called); + assert(0 == unsized_delete_nothrow_called); + assert(1 == aligned_delete_called); + } +} diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp new file mode 100644 index 00000000000..69be9b31fee --- /dev/null +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp @@ -0,0 +1,77 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// test operator new + +// asan and msan will not call the new handler. +// UNSUPPORTED: sanitizer-new-delete + +#include <new> +#include <cstddef> +#include <cassert> +#include <cstdint> +#include <limits> + +#include "test_macros.h" + +constexpr auto OverAligned = alignof(std::max_align_t) * 2; + +int new_handler_called = 0; + +void new_handler() +{ + ++new_handler_called; + std::set_new_handler(0); +} + +int A_constructed = 0; + +struct alignas(OverAligned) A +{ + A() { ++A_constructed;} + ~A() { --A_constructed;} +}; + +void test_throw_max_size() { +#ifndef TEST_HAS_NO_EXCEPTIONS + std::set_new_handler(new_handler); + try + { + void* vp = operator new[] (std::numeric_limits<std::size_t>::max(), + static_cast<std::align_val_t>(32)); + ((void)vp); + assert(false); + } + catch (std::bad_alloc&) + { + assert(new_handler_called == 1); + } + catch (...) + { + assert(false); + } +#endif +} + +int main() +{ + { + A* ap = new A[2]; + assert(ap); + assert(reinterpret_cast<std::uintptr_t>(ap) % OverAligned == 0); + assert(A_constructed == 2); + delete [] ap; + assert(A_constructed == 0); + } + { + test_throw_max_size(); + } +} diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp new file mode 100644 index 00000000000..76b50346713 --- /dev/null +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// test operator new (nothrow) + +// asan and msan will not call the new handler. +// UNSUPPORTED: sanitizer-new-delete + +#include <new> +#include <cstddef> +#include <cstdint> +#include <cassert> +#include <limits> + +#include "test_macros.h" + +constexpr auto OverAligned = alignof(std::max_align_t) * 2; + +int new_handler_called = 0; + +void new_handler() +{ + ++new_handler_called; + std::set_new_handler(0); +} + +int A_constructed = 0; + +struct alignas(OverAligned) A +{ + A() { ++A_constructed; } + ~A() { --A_constructed; } +}; + +void test_max_alloc() { + std::set_new_handler(new_handler); + auto do_test = []() { + void* vp = operator new [](std::numeric_limits<std::size_t>::max(), + std::align_val_t(OverAligned), + std::nothrow); + assert(new_handler_called == 1); + assert(vp == 0); + }; +#ifndef TEST_HAS_NO_EXCEPTIONS + try + { + do_test(); + } + catch (...) + { + assert(false); + } +#else + do_test(); +#endif +} + +int main() +{ + { + A* ap = new(std::nothrow) A[3]; + assert(ap); + assert(reinterpret_cast<std::uintptr_t>(ap) % OverAligned == 0); + assert(A_constructed == 3); + delete [] ap; + assert(!A_constructed); + } + { + test_max_alloc(); + } +} diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp new file mode 100644 index 00000000000..299be7d1941 --- /dev/null +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp @@ -0,0 +1,84 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// test operator new nothrow by replacing only operator new + +// UNSUPPORTED: sanitizer-new-delete + +// TODO Investigate why UBSAN prevents nothrow new from calling our replacement. +// XFAIL: ubsan + +#include <new> +#include <cstddef> +#include <cstdlib> +#include <cassert> +#include <limits> + + +constexpr auto OverAligned = alignof(std::max_align_t) * 2; + +int A_constructed = 0; + +struct alignas(OverAligned) A +{ + A() {++A_constructed;} + ~A() {--A_constructed;} +}; + +int B_constructed = 0; + +struct B { + std::max_align_t member; + B() { ++B_constructed; } + ~B() { --B_constructed; } +}; + +int new_called = 0; +alignas(OverAligned) char Buff[OverAligned * 3]; + +void* operator new[](std::size_t s, std::align_val_t a) throw(std::bad_alloc) +{ + assert(!new_called); + assert(s <= sizeof(Buff)); + assert(static_cast<std::size_t>(a) == OverAligned); + ++new_called; + return Buff; +} + +void operator delete[](void* p, std::align_val_t a) throw() +{ + assert(p == Buff); + assert(static_cast<std::size_t>(a) == OverAligned); + assert(new_called); + --new_called; +} + +int main() +{ + { + A* ap = new (std::nothrow) A[2]; + assert(ap); + assert(A_constructed == 2); + assert(new_called); + delete [] ap; + assert(A_constructed == 0); + assert(!new_called); + } + { + B* bp = new (std::nothrow) B[2]; + assert(bp); + assert(B_constructed == 2); + assert(!new_called); + delete [] bp; + assert(!new_called); + assert(!B_constructed); + } +} diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_replace.pass.cpp new file mode 100644 index 00000000000..6ea23ffe9f5 --- /dev/null +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_replace.pass.cpp @@ -0,0 +1,82 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// test operator new replacement + +// UNSUPPORTED: sanitizer-new-delete + +#include <new> +#include <cstddef> +#include <cstdlib> +#include <cstdint> +#include <cassert> +#include <limits> + +constexpr auto OverAligned = alignof(std::max_align_t) * 2; + +int A_constructed = 0; + +struct alignas(OverAligned) A { + A() { ++A_constructed;} + ~A() { --A_constructed;} +}; + + +int B_constructed = 0; + +struct alignas(std::max_align_t) B +{ + std::max_align_t member; + B() { ++B_constructed;} + ~B() { --B_constructed;} +}; + +int new_called = 0; + +alignas(OverAligned) char DummyData[OverAligned * 4]; + +void* operator new[](std::size_t s, std::align_val_t a) throw(std::bad_alloc) +{ + assert(new_called == 0); // We already allocated + assert(s <= sizeof(DummyData)); + assert(static_cast<std::size_t>(a) == OverAligned); + ++new_called; + return DummyData; +} + +void operator delete[](void* p, std::align_val_t a) throw() +{ + assert(new_called == 1); + --new_called; + assert(p == DummyData); +} + + +int main() +{ + { + A* ap = new A[3]; + assert(ap); + assert(A_constructed == 3); + assert(new_called); + delete [] ap; + assert(!A_constructed); + assert(!new_called); + } + { + B* bp = new B[3]; + assert(bp); + assert(B_constructed == 3); + assert(!new_called); + delete [] bp; + assert(!new_called); + } +} diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp new file mode 100644 index 00000000000..11d29015a4e --- /dev/null +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp @@ -0,0 +1,83 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// test aligned operator delete replacement. + +// UNSUPPORTED: sanitizer-new-delete, c++98, c++03, c++11, c++14 + +// Older Clang versions do not support this +// XFAIL: clang-3, apple-clang + +// None of the current GCC compilers support this. +// XFAIL: gcc-4, gcc-5, gcc-6 + +#include <new> +#include <cstddef> +#include <cstdlib> +#include <cassert> + +constexpr auto OverAligned = alignof(std::max_align_t) * 2; + +int unsized_delete_called = 0; +int unsized_delete_nothrow_called = 0; +int aligned_delete_called = 0; + +void reset() { + unsized_delete_called = 0; + unsized_delete_nothrow_called = 0; + aligned_delete_called = 0; +} + +void operator delete(void* p) throw() +{ + ++unsized_delete_called; + std::free(p); +} + +void operator delete(void* p, const std::nothrow_t&) throw() +{ + ++unsized_delete_nothrow_called; + std::free(p); +} + +void operator delete(void* p, std::align_val_t a) throw() +{ + ++aligned_delete_called; + std::free(p); +} + +struct alignas(OverAligned) A {}; +struct alignas(std::max_align_t) B {}; + +int main() +{ + { + B *x = new B; + assert(0 == unsized_delete_called); + assert(0 == unsized_delete_nothrow_called); + assert(0 == aligned_delete_called); + + delete x; + assert(1 == unsized_delete_called); + assert(0 == unsized_delete_nothrow_called); + assert(0 == aligned_delete_called); + } + reset(); + { + A *x = new A; + assert(0 == unsized_delete_called); + assert(0 == unsized_delete_nothrow_called); + assert(0 == aligned_delete_called); + + delete x; + assert(0 == unsized_delete_called); + assert(0 == unsized_delete_nothrow_called); + assert(1 == aligned_delete_called); + } +} diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp new file mode 100644 index 00000000000..1be78fb73d2 --- /dev/null +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp @@ -0,0 +1,77 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// test operator new + +// asan and msan will not call the new handler. +// UNSUPPORTED: sanitizer-new-delete + +#include <new> +#include <cstddef> +#include <cassert> +#include <cstdint> +#include <limits> + +#include "test_macros.h" + +constexpr auto OverAligned = alignof(std::max_align_t) * 2; + +int new_handler_called = 0; + +void new_handler() +{ + ++new_handler_called; + std::set_new_handler(0); +} + +bool A_constructed = false; + +struct alignas(OverAligned) A +{ + A() {A_constructed = true;} + ~A() {A_constructed = false;} +}; + +void test_throw_max_size() { +#ifndef TEST_HAS_NO_EXCEPTIONS + std::set_new_handler(new_handler); + try + { + void* vp = operator new (std::numeric_limits<std::size_t>::max(), + static_cast<std::align_val_t>(32)); + ((void)vp); + assert(false); + } + catch (std::bad_alloc&) + { + assert(new_handler_called == 1); + } + catch (...) + { + assert(false); + } +#endif +} + +int main() +{ + { + A* ap = new A; + assert(ap); + assert(reinterpret_cast<std::uintptr_t>(ap) % OverAligned == 0); + assert(A_constructed); + delete ap; + assert(!A_constructed); + } + { + test_throw_max_size(); + } +} diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp new file mode 100644 index 00000000000..89e5dc820c8 --- /dev/null +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// test operator new (nothrow) + +// asan and msan will not call the new handler. +// UNSUPPORTED: sanitizer-new-delete + +#include <new> +#include <cstddef> +#include <cstdint> +#include <cassert> +#include <limits> + +#include "test_macros.h" + +constexpr auto OverAligned = alignof(std::max_align_t) * 2; + +int new_handler_called = 0; + +void new_handler() +{ + ++new_handler_called; + std::set_new_handler(0); +} + +bool A_constructed = false; + +struct alignas(OverAligned) A +{ + A() {A_constructed = true;} + ~A() {A_constructed = false;} +}; + +void test_max_alloc() { + std::set_new_handler(new_handler); + auto do_test = []() { + void* vp = operator new (std::numeric_limits<std::size_t>::max(), + std::align_val_t(OverAligned), + std::nothrow); + assert(new_handler_called == 1); + assert(vp == 0); + }; +#ifndef TEST_HAS_NO_EXCEPTIONS + try + { + do_test(); + } + catch (...) + { + assert(false); + } +#else + do_test(); +#endif +} + +int main() +{ + { + A* ap = new(std::nothrow) A; + assert(ap); + assert(reinterpret_cast<std::uintptr_t>(ap) % OverAligned == 0); + assert(A_constructed); + delete ap; + assert(!A_constructed); + } + { + test_max_alloc(); + } +} diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp new file mode 100644 index 00000000000..7a52e98ddf3 --- /dev/null +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp @@ -0,0 +1,85 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// test operator new nothrow by replacing only operator new + +// UNSUPPORTED: sanitizer-new-delete + +// TODO Investigate why UBSAN prevents nothrow new from calling our replacement. +// XFAIL: ubsan + +#include <new> +#include <cstddef> +#include <cstdlib> +#include <cassert> +#include <limits> + + +constexpr auto OverAligned = alignof(std::max_align_t) * 2; + +bool A_constructed = false; + +struct alignas(OverAligned) A +{ + A() {A_constructed = true;} + ~A() {A_constructed = false;} +}; + +bool B_constructed = false; + +struct B { + std::max_align_t member; + B() { B_constructed = true; } + ~B() { B_constructed = false; } +}; + +int new_called = 0; +alignas(OverAligned) char Buff[OverAligned * 2]; + +void* operator new(std::size_t s, std::align_val_t a) throw(std::bad_alloc) +{ + assert(!new_called); + assert(s <= sizeof(Buff)); + assert(static_cast<std::size_t>(a) == OverAligned); + ++new_called; + return Buff; +} + +void operator delete(void* p, std::align_val_t a) throw() +{ + assert(p == Buff); + assert(static_cast<std::size_t>(a) == OverAligned); + assert(new_called); + --new_called; +} + + +int main() +{ + { + A* ap = new (std::nothrow) A; + assert(ap); + assert(A_constructed); + assert(new_called); + delete ap; + assert(!A_constructed); + assert(!new_called); + } + { + B* bp = new (std::nothrow) B; + assert(bp); + assert(B_constructed); + assert(!new_called); + delete bp; + assert(!new_called); + assert(!B_constructed); + } +} diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_replace.pass.cpp new file mode 100644 index 00000000000..dd6fc676e96 --- /dev/null +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_replace.pass.cpp @@ -0,0 +1,82 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// test operator new replacement + +// UNSUPPORTED: sanitizer-new-delete + +#include <new> +#include <cstddef> +#include <cstdlib> +#include <cstdint> +#include <cassert> +#include <limits> + +constexpr auto OverAligned = alignof(std::max_align_t) * 2; + +bool A_constructed = false; + +struct alignas(OverAligned) A { + A() {A_constructed = true;} + ~A() {A_constructed = false;} +}; + + +bool B_constructed = false; + +struct alignas(std::max_align_t) B +{ + std::max_align_t member; + B() {B_constructed = true;} + ~B() {B_constructed = false;} +}; + +int new_called = 0; + +alignas(OverAligned) char DummyData[OverAligned]; + +void* operator new(std::size_t s, std::align_val_t a) throw(std::bad_alloc) +{ + assert(new_called == 0); // We already allocated + assert(s <= sizeof(DummyData)); + assert(static_cast<std::size_t>(a) == OverAligned); + ++new_called; + return DummyData; +} + +void operator delete(void* p, std::align_val_t a) throw() +{ + assert(new_called == 1); + --new_called; + assert(p == DummyData); +} + + +int main() +{ + { + A* ap = new A; + assert(ap); + assert(A_constructed); + assert(new_called); + delete ap; + assert(!A_constructed); + assert(!new_called); + } + { + B* bp = new B; + assert(bp); + assert(B_constructed); + assert(!new_called); + delete bp; + assert(!new_called); + } +} |