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