1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9// void* operator new[](std::size_t, std::align_val_t);
10
11// Test that we can replace the operator by replacing `operator new(std::size_t, std::align_val_t)` (the non-array version).
12
13// UNSUPPORTED: c++03, c++11, c++14
14// UNSUPPORTED: sanitizer-new-delete
15
16// XFAIL: LIBCXX-AIX-FIXME
17
18// Libc++ when built for z/OS doesn't contain the aligned allocation functions,
19// nor does the dynamic library shipped with z/OS.
20// XFAIL: target={{.+}}-zos{{.*}}
21
22#include <new>
23#include <cstddef>
24#include <cstdlib>
25#include <cstdint>
26#include <cassert>
27#include <limits>
28
29#include "test_macros.h"
30#include "../types.h"
31
32int new_called = 0;
33int delete_called = 0;
34
35alignas(OverAligned) char DummyData[alignof(OverAligned) * 3];
36
37TEST_WORKAROUND_BUG_109234844_WEAK
38void* operator new(std::size_t s, std::align_val_t a) {
39 assert(s <= sizeof(DummyData));
40 assert(static_cast<std::size_t>(a) == alignof(OverAligned));
41 ++new_called;
42 return DummyData;
43}
44
45void operator delete(void*, std::align_val_t) noexcept {
46 ++delete_called;
47 // nothing to delete, we didn't actually allocate in `operator new`
48}
49
50int main(int, char**) {
51 // Test with an overaligned type
52 {
53 new_called = delete_called = 0;
54 OverAligned* dummy_data_block = new OverAligned[3];
55 OverAligned* x = DoNotOptimize(dummy_data_block);
56 ASSERT_WITH_OPERATOR_NEW_FALLBACKS(static_cast<void*>(x) == DummyData);
57 ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_called == 1);
58
59 delete[] dummy_data_block;
60 ASSERT_WITH_OPERATOR_NEW_FALLBACKS(delete_called == 1);
61 }
62
63 // Test with a type that is right on the verge of being overaligned
64 {
65 new_called = delete_called = 0;
66 MaxAligned* x = DoNotOptimize(new MaxAligned[3]);
67 assert(x != nullptr);
68 assert(new_called == 0);
69
70 delete[] x;
71 assert(delete_called == 0);
72 }
73
74 // Test with a type that is clearly not overaligned
75 {
76 new_called = delete_called = 0;
77 int* x = DoNotOptimize(new int[3]);
78 assert(x != nullptr);
79 assert(new_called == 0);
80
81 delete[] x;
82 assert(delete_called == 0);
83 }
84
85 return 0;
86}
87

source code of libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align.replace.indirect.pass.cpp