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// UNSUPPORTED: c++03, c++11, c++14
12
13// asan and msan will not call the new handler.
14// UNSUPPORTED: sanitizer-new-delete
15
16// GCC warns about allocating numeric_limits<size_t>::max() being too large (which we test here)
17// ADDITIONAL_COMPILE_FLAGS(gcc): -Wno-alloc-size-larger-than
18
19// Libc++ when built for z/OS doesn't contain the aligned allocation functions,
20// nor does the dynamic library shipped with z/OS.
21// XFAIL: target={{.+}}-zos{{.*}}
22
23#include <new>
24#include <cstddef>
25#include <cassert>
26#include <cstdint>
27#include <limits>
28
29#include "test_macros.h"
30#include "../types.h"
31
32int new_handler_called = 0;
33
34void my_new_handler() {
35 ++new_handler_called;
36 std::set_new_handler(nullptr);
37}
38
39int main(int, char**) {
40 test_with_interesting_alignments(f: [](std::size_t size, std::size_t alignment) {
41 void* x = operator new[](size, static_cast<std::align_val_t>(alignment));
42 assert(x != nullptr);
43 assert(reinterpret_cast<std::uintptr_t>(x) % alignment == 0);
44 operator delete[](x, static_cast<std::align_val_t>(alignment));
45 });
46
47 // Test that the new handler is called if allocation fails
48 {
49#ifndef TEST_HAS_NO_EXCEPTIONS
50 std::set_new_handler(my_new_handler);
51 try {
52 void* x = operator new[] (std::numeric_limits<std::size_t>::max(),
53 static_cast<std::align_val_t>(32));
54 (void)x;
55 assert(false);
56 } catch (std::bad_alloc const&) {
57 assert(new_handler_called == 1);
58 } catch (...) {
59 assert(false);
60 }
61#endif
62 }
63
64 // Test that a new expression constructs the right object
65 // and a delete expression deletes it
66 {
67 LifetimeInformation infos[3];
68 TrackLifetimeOverAligned* x = new TrackLifetimeOverAligned[3]{infos[0], infos[1], infos[2]};
69 assert(x != nullptr);
70 assert(reinterpret_cast<std::uintptr_t>(x) % alignof(TrackLifetimeOverAligned) == 0);
71
72 void* addresses[3] = {&x[0], &x[1], &x[2]};
73 assert(infos[0].address_constructed == addresses[0]);
74 assert(infos[1].address_constructed == addresses[1]);
75 assert(infos[2].address_constructed == addresses[2]);
76
77 delete[] x;
78 assert(infos[0].address_destroyed == addresses[0]);
79 assert(infos[1].address_destroyed == addresses[1]);
80 assert(infos[2].address_destroyed == addresses[2]);
81 }
82
83 return 0;
84}
85

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