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 // <memory>
10 
11 // allocator:
12 // T* allocate(size_t n, const void* hint);
13 
14 // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS
15 // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
16 
17 #include <memory>
18 #include <cassert>
19 #include <cstddef>       // for std::max_align_t
20 
21 #include "test_macros.h"
22 #include "count_new.h"
23 
24 
25 #ifdef TEST_HAS_NO_ALIGNED_ALLOCATION
26 static const bool UsingAlignedNew = false;
27 #else
28 static const bool UsingAlignedNew = true;
29 #endif
30 
31 #ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__
32 static const size_t MaxAligned = __STDCPP_DEFAULT_NEW_ALIGNMENT__;
33 #else
34 static const size_t MaxAligned = std::alignment_of<std::max_align_t>::value;
35 #endif
36 
37 static const size_t OverAligned = MaxAligned * 2;
38 
39 
40 template <size_t Align>
TEST_ALIGNAS(Align)41 struct TEST_ALIGNAS(Align) AlignedType {
42   char data;
43   static int constructed;
44   AlignedType() { ++constructed; }
45   AlignedType(AlignedType const&) { ++constructed; }
46   ~AlignedType() { --constructed; }
47 };
48 template <size_t Align>
49 int AlignedType<Align>::constructed = 0;
50 
51 
52 template <size_t Align>
test_aligned()53 void test_aligned() {
54   typedef AlignedType<Align> T;
55   T::constructed = 0;
56   globalMemCounter.reset();
57   std::allocator<T> a;
58   const bool IsOverAlignedType = Align > MaxAligned;
59   const bool ExpectAligned = IsOverAlignedType && UsingAlignedNew;
60   {
61     globalMemCounter.last_new_size = 0;
62     globalMemCounter.last_new_align = 0;
63     T* volatile ap2 = a.allocate(11, (const void*)5);
64     DoNotOptimize(ap2);
65     assert(globalMemCounter.checkOutstandingNewEq(1));
66     assert(globalMemCounter.checkNewCalledEq(1));
67     assert(globalMemCounter.checkAlignedNewCalledEq(ExpectAligned));
68     assert(globalMemCounter.checkLastNewSizeEq(11 * sizeof(T)));
69     assert(globalMemCounter.checkLastNewAlignEq(ExpectAligned ? Align : 0));
70     assert(T::constructed == 0);
71     globalMemCounter.last_delete_align = 0;
72     a.deallocate(ap2, 11);
73     DoNotOptimize(ap2);
74     assert(globalMemCounter.checkOutstandingNewEq(0));
75     assert(globalMemCounter.checkDeleteCalledEq(1));
76     assert(globalMemCounter.checkAlignedDeleteCalledEq(ExpectAligned));
77     assert(globalMemCounter.checkLastDeleteAlignEq(ExpectAligned ? Align : 0));
78     assert(T::constructed == 0);
79   }
80 }
81 
main(int,char **)82 int main(int, char**) {
83     test_aligned<1>();
84     test_aligned<2>();
85     test_aligned<4>();
86     test_aligned<8>();
87     test_aligned<16>();
88     test_aligned<MaxAligned>();
89     test_aligned<OverAligned>();
90     test_aligned<OverAligned * 2>();
91 
92   return 0;
93 }
94