Skip to content
16 changes: 16 additions & 0 deletions tests/std/include/new_counter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@ void* operator new(size_t size) {
return p;
}

#ifdef __cpp_aligned_new
void* operator new(size_t, std::align_val_t) {
abort();
}
#endif // ^^^ defined(__cpp_aligned_new) ^^^

void* operator new(size_t size, const std::nothrow_t&) noexcept {
if (std_testing::g_total_news == std_testing::g_maximum_news) {
Expand All @@ -50,9 +52,11 @@ void* operator new(size_t size, const std::nothrow_t&) noexcept {
return malloc(size);
}

#ifdef __cpp_aligned_new
void* operator new(size_t, std::align_val_t, const std::nothrow_t&) noexcept {
abort();
}
#endif // ^^^ defined(__cpp_aligned_new) ^^^

void operator delete(void* ptr) noexcept {
::operator delete(ptr, std::nothrow);
Expand All @@ -62,9 +66,11 @@ void operator delete(void* ptr, size_t) noexcept {
::operator delete(ptr, std::nothrow);
}

#ifdef __cpp_aligned_new
void operator delete(void*, std::align_val_t) noexcept {
abort();
}
#endif // ^^^ defined(__cpp_aligned_new) ^^^

void operator delete(void* ptr, const std::nothrow_t&) noexcept {
if (ptr) {
Expand All @@ -74,25 +80,31 @@ void operator delete(void* ptr, const std::nothrow_t&) noexcept {
}
}

#ifdef __cpp_aligned_new
void operator delete(void*, std::align_val_t, const std::nothrow_t&) noexcept {
abort();
}
#endif // ^^^ defined(__cpp_aligned_new) ^^^

void* operator new[](size_t size) {
return ::operator new(size);
}

#ifdef __cpp_aligned_new
void* operator new[](size_t, std::align_val_t) {
abort();
}
#endif // ^^^ defined(__cpp_aligned_new) ^^^

void* operator new[](size_t size, const std::nothrow_t&) noexcept {
return ::operator new(size, std::nothrow);
}

#ifdef __cpp_aligned_new
void* operator new[](size_t, std::align_val_t, const std::nothrow_t&) noexcept {
abort();
}
#endif // ^^^ defined(__cpp_aligned_new) ^^^

void operator delete[](void* ptr) noexcept {
::operator delete(ptr);
Expand All @@ -102,20 +114,24 @@ void operator delete[](void* ptr, size_t size) noexcept {
::operator delete(ptr, size);
}

#ifdef __cpp_aligned_new
void operator delete[](void*, std::align_val_t) noexcept {
abort();
}

void operator delete[](void*, size_t, std::align_val_t) noexcept {
abort();
}
#endif // ^^^ defined(__cpp_aligned_new) ^^^

void operator delete[](void* ptr, const std::nothrow_t&) noexcept {
::operator delete(ptr, std::nothrow);
}

#ifdef __cpp_aligned_new
void operator delete[](void*, std::align_val_t, const std::nothrow_t&) noexcept {
abort();
}
#endif // ^^^ defined(__cpp_aligned_new) ^^^

#pragma warning(pop)
2 changes: 2 additions & 0 deletions tests/std/include/test_header_units_and_modules.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,9 @@ void test_new() {

static_assert(is_class_v<bad_alloc>);
static_assert(is_class_v<bad_array_new_length>);
#ifdef __cpp_aligned_new
static_assert(is_same_v<underlying_type_t<align_val_t>, size_t>);
#endif // ^^^ defined(__cpp_aligned_new) ^^^
static_assert(is_class_v<nothrow_t>);

bool caught_bad_alloc = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ void operator delete(void* const mem) noexcept {
free(mem);
}

#ifdef __cpp_aligned_new
void* operator new(const size_t size, const align_val_t al) {
++alloc_count;
return check_alloc(_aligned_malloc(adjust_alloc_size(size), static_cast<size_t>(al)));
Expand All @@ -47,6 +48,7 @@ void operator delete(void* const mem, align_val_t) noexcept {
++dealloc_count;
_aligned_free(mem);
}
#endif // ^^^ defined(__cpp_aligned_new) ^^^

struct alloc_checker {
explicit alloc_checker(const int expected_delta_) : expected_delta(expected_delta_) {}
Expand Down Expand Up @@ -90,7 +92,9 @@ struct alignas(128) large_callable {
const int context = 1729;

int operator()(const copy_counter& counter) const noexcept {
#ifdef __cpp_aligned_new
assert((reinterpret_cast<uintptr_t>(this) & 0x7f) == 0);
#endif // ^^^ defined(__cpp_aligned_new) ^^^
assert(context == 1729);
return counter.count;
}
Expand Down
4 changes: 4 additions & 0 deletions tests/std/tests/P0035R4_over_aligned_allocation/test.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#if !defined(__cpp_aligned_new)
#error overaligned allocation does not work with /Zc:alignedNew-
#endif

#define _ENABLE_EXTENDED_ALIGNED_STORAGE
#define _HAS_DEPRECATED_TEMPORARY_BUFFER 1
#define _SILENCE_CXX17_TEMPORARY_BUFFER_DEPRECATION_WARNING
Expand Down
4 changes: 4 additions & 0 deletions tests/std/tests/P0220R1_any/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
// Yes, this is an awkward hand process; notably the required headers can change without notice. We should investigate
// running the libc++ tests directly in all of our configurations so we needn't replicate this subset of files.

#if !defined(__cpp_aligned_new)
#error This test relies on libc++ machinery which assumes overaligned allocation support since C++17
#endif

#define _LIBCXX_IN_DEVCRT
#include <msvc_stdlib_force_include.h> // Must precede any other libc++ headers
#include <stdlib.h>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#if !defined(__cpp_aligned_new)
#error pmr does not completely work with /Zc:alignedNew-
#endif

#define _SILENCE_CXX23_ALIGNED_UNION_DEPRECATION_WARNING

#include <algorithm>
Expand Down
12 changes: 12 additions & 0 deletions tests/std/tests/P0674R1_make_shared_for_arrays/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,9 @@ void test_make_shared_not_array() {

shared_ptr<HighlyAligned> p5 = make_shared<HighlyAligned>();
assert_shared_use_get(p5);
#ifdef __cpp_aligned_new
assert(reinterpret_cast<uintptr_t>(p5.get()) % alignof(HighlyAligned) == 0);
#endif // ^^^ defined(__cpp_aligned_new) ^^^
assert(p5->a == 0 && p5->b == 0 && p5->c == 0 && p5->d == 0);
}

Expand Down Expand Up @@ -209,7 +211,9 @@ void test_make_shared_array_known_bounds() {

shared_ptr<HighlyAligned[6]> p6 = make_shared<HighlyAligned[6]>();
assert_shared_use_get(p6);
#ifdef __cpp_aligned_new
assert(reinterpret_cast<uintptr_t>(p6.get()) % alignof(HighlyAligned) == 0);
#endif // ^^^ defined(__cpp_aligned_new) ^^^
for (int i = 0; i < 6; ++i) {
assert(p6[i].a == 0 && p6[i].b == 0 && p6[i].c == 0 && p6[i].d == 0);
}
Expand Down Expand Up @@ -279,7 +283,9 @@ void test_make_shared_array_unknown_bounds() {

shared_ptr<HighlyAligned[]> p7 = make_shared<HighlyAligned[]>(7u);
assert_shared_use_get(p7);
#ifdef __cpp_aligned_new
assert(reinterpret_cast<uintptr_t>(p7.get()) % alignof(HighlyAligned) == 0);
#endif // ^^^ defined(__cpp_aligned_new) ^^^
for (int i = 0; i < 7; ++i) {
assert(p7[i].a == 0 && p7[i].b == 0 && p7[i].c == 0 && p7[i].d == 0);
}
Expand Down Expand Up @@ -422,7 +428,9 @@ void test_allocate_shared_not_array() {
{
shared_ptr<HighlyAligned> p5 = allocate_shared<HighlyAligned>(a5);
assert_shared_use_get(p5);
#ifdef __cpp_aligned_new
assert(reinterpret_cast<uintptr_t>(p5.get()) % alignof(HighlyAligned) == 0);
#endif // ^^^ defined(__cpp_aligned_new) ^^^
assert(p5->a == 0 && p5->b == 0 && p5->c == 0 && p5->d == 0);
}
assert_construct_destruct_equal();
Expand Down Expand Up @@ -502,7 +510,9 @@ void test_allocate_shared_array_known_bounds() {
{
shared_ptr<HighlyAligned[6]> p6 = allocate_shared<HighlyAligned[6]>(a6);
assert_shared_use_get(p6);
#ifdef __cpp_aligned_new
assert(reinterpret_cast<uintptr_t>(p6.get()) % alignof(HighlyAligned) == 0);
#endif // ^^^ defined(__cpp_aligned_new) ^^^
for (int i = 0; i < 6; ++i) {
assert(p6[i].a == 0 && p6[i].b == 0 && p6[i].c == 0 && p6[i].d == 0);
}
Expand Down Expand Up @@ -603,7 +613,9 @@ void test_allocate_shared_array_unknown_bounds() {
{
shared_ptr<HighlyAligned[]> p7 = allocate_shared<HighlyAligned[]>(a7, 7u);
assert_shared_use_get(p7);
#ifdef __cpp_aligned_new
assert(reinterpret_cast<uintptr_t>(p7.get()) % alignof(HighlyAligned) == 0);
#endif // ^^^ defined(__cpp_aligned_new) ^^^
for (int i = 0; i < 7; ++i) {
assert(p7[i].a == 0 && p7[i].b == 0 && p7[i].c == 0 && p7[i].d == 0);
}
Expand Down
14 changes: 14 additions & 0 deletions tests/std/tests/P1020R1_smart_pointer_for_overwrite/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ void* operator new(size_t size, const nothrow_t&) noexcept {
return result;
}

#ifdef __cpp_aligned_new
void* operator new(size_t size, align_val_t align) {
void* const p = ::operator new(size, align, nothrow);

Expand All @@ -66,6 +67,7 @@ void* operator new(size_t size, align_val_t align, const nothrow_t&) noexcept {

return result;
}
#endif // ^^^ defined(__cpp_aligned_new) ^^^

template <typename T, typename = void>
struct unique_is_for_overwritable : false_type {};
Expand Down Expand Up @@ -188,7 +190,9 @@ void test_make_shared_for_overwrite() {
assert(p1->value == initializedValue);

auto p2 = make_shared_for_overwrite_assert<HighlyAligned>();
#ifdef __cpp_aligned_new
assert(reinterpret_cast<uintptr_t>(p2.get()) % alignof(HighlyAligned) == 0);
#endif // ^^^ defined(__cpp_aligned_new) ^^^
assert_uninitialized(addressof(*p2), sizeof(HighlyAligned));

auto p3 = make_shared_for_overwrite_assert<int[100]>();
Expand All @@ -202,7 +206,9 @@ void test_make_shared_for_overwrite() {
}

auto p5 = make_shared_for_overwrite_assert<HighlyAligned[10]>();
#ifdef __cpp_aligned_new
assert(reinterpret_cast<uintptr_t>(p5.get()) % alignof(HighlyAligned) == 0);
#endif // ^^^ defined(__cpp_aligned_new) ^^^
assert_uninitialized(addressof(p5[0]), sizeof(HighlyAligned) * 10u);

auto p6 = make_shared_for_overwrite_assert<DefaultInitializableInt[]>(100u);
Expand All @@ -225,7 +231,9 @@ void test_make_shared_for_overwrite() {
auto p9 = make_shared_for_overwrite_assert<int[]>(0u); // p9 cannot be dereferenced

auto p10 = make_shared_for_overwrite_assert<HighlyAligned[]>(10u);
#ifdef __cpp_aligned_new
assert(reinterpret_cast<uintptr_t>(p10.get()) % alignof(HighlyAligned) == 0);
#endif // ^^^ defined(__cpp_aligned_new) ^^^
assert_uninitialized(addressof(p10[0]), sizeof(HighlyAligned) * 10u);

test_make_shared_init_destruct_order<ReportAddress[5]>(); // success one dimensional
Expand Down Expand Up @@ -280,7 +288,9 @@ void test_allocate_shared_for_overwrite() {

allocator<HighlyAligned> a2{};
auto p2 = allocate_shared_for_overwrite_assert<HighlyAligned>(a2);
#ifdef __cpp_aligned_new
assert(reinterpret_cast<uintptr_t>(p2.get()) % alignof(HighlyAligned) == 0);
#endif // ^^^ defined(__cpp_aligned_new) ^^^
assert_uninitialized(addressof(*p2), sizeof(HighlyAligned));

auto p3 = allocate_shared_for_overwrite_assert<int[100]>(a0);
Expand All @@ -294,7 +304,9 @@ void test_allocate_shared_for_overwrite() {
}

auto p5 = allocate_shared_for_overwrite_assert<HighlyAligned[10]>(a2);
#ifdef __cpp_aligned_new
assert(reinterpret_cast<uintptr_t>(p5.get()) % alignof(HighlyAligned) == 0);
#endif // ^^^ defined(__cpp_aligned_new) ^^^
assert_uninitialized(addressof(p5[0]), sizeof(HighlyAligned) * 10u);

auto p6 = allocate_shared_for_overwrite_assert<DefaultInitializableInt[]>(a1, 100u);
Expand All @@ -317,7 +329,9 @@ void test_allocate_shared_for_overwrite() {
auto p9 = allocate_shared_for_overwrite_assert<int[]>(a0, 0u); // p9 cannot be dereferenced

auto p10 = allocate_shared_for_overwrite_assert<HighlyAligned[]>(a2, 10u);
#ifdef __cpp_aligned_new
assert(reinterpret_cast<uintptr_t>(p10.get()) % alignof(HighlyAligned) == 0);
#endif // ^^^ defined(__cpp_aligned_new) ^^^
assert_uninitialized(addressof(p10[0]), sizeof(HighlyAligned) * 10u);

test_allocate_shared_init_destruct_order<ReportAddress[5]>(); // success one dimensional
Expand Down
4 changes: 4 additions & 0 deletions tests/std/tests/P2502R2_generator/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,9 +306,11 @@ void dynamic_allocator_test() {
test_one<gen_traits<int>, int, int&&, int&&>(
g(allocator_arg, StatefulAlloc<float>{1729}, 1024), views::iota(0, 1024));
#endif // ^^^ no workaround ^^^
#ifdef __cpp_aligned_new
pmr::synchronized_pool_resource pool;
test_one<gen_traits<int>, int, int&&, int&&>(
g(allocator_arg, pmr::polymorphic_allocator<>{&pool}, 1024), views::iota(0, 1024));
#endif // ^^^ defined(__cpp_aligned_new) ^^^
}

static atomic<bool> allow_allocation{true};
Expand All @@ -330,6 +332,7 @@ void operator delete(void* const p, size_t) noexcept {
free(p);
}

#ifdef __cpp_aligned_new
void* operator new(const size_t n, const align_val_t al) {
if (allow_allocation) {
if (void* const result = ::_aligned_malloc(n, static_cast<size_t>(al))) {
Expand All @@ -346,6 +349,7 @@ void operator delete(void* const p, align_val_t) noexcept {
void operator delete(void* const p, size_t, align_val_t) noexcept {
::_aligned_free(p);
}
#endif // ^^^ defined(__cpp_aligned_new) ^^^

class malloc_resource final : public pmr::memory_resource {
private:
Expand Down