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 // pointer allocate(size_type n, allocator<void>::const_pointer hint=0); 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 size_t MaxAligned = __STDCPP_DEFAULT_NEW_ALIGNMENT__; 30 #else 31 static const size_t MaxAligned = std::alignment_of<std::max_align_t>::value; 32 #endif 33 34 static const size_t OverAligned = MaxAligned * 2; 35 36 37 template <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 <size_t Align> 46 int AlignedType<Align>::constructed = 0; 47 48 49 template <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 globalMemCounter.reset(); 79 { 80 globalMemCounter.last_new_size = 0; 81 globalMemCounter.last_new_align = 0; 82 T* volatile ap2 = a.allocate(11, (const void*)5); 83 DoNotOptimize(ap2); 84 assert(globalMemCounter.checkOutstandingNewEq(1)); 85 assert(globalMemCounter.checkNewCalledEq(1)); 86 assert(globalMemCounter.checkAlignedNewCalledEq(ExpectAligned)); 87 assert(globalMemCounter.checkLastNewSizeEq(11 * sizeof(T))); 88 assert(globalMemCounter.checkLastNewAlignEq(ExpectAligned ? Align : 0)); 89 assert(T::constructed == 0); 90 globalMemCounter.last_delete_align = 0; 91 a.deallocate(ap2, 11); 92 DoNotOptimize(ap2); 93 assert(globalMemCounter.checkOutstandingNewEq(0)); 94 assert(globalMemCounter.checkDeleteCalledEq(1)); 95 assert(globalMemCounter.checkAlignedDeleteCalledEq(ExpectAligned)); 96 assert(globalMemCounter.checkLastDeleteAlignEq(ExpectAligned ? Align : 0)); 97 assert(T::constructed == 0); 98 } 99 } 100 main(int,char **)101int main(int, char**) { 102 test_aligned<1>(); 103 test_aligned<2>(); 104 test_aligned<4>(); 105 test_aligned<8>(); 106 test_aligned<16>(); 107 test_aligned<MaxAligned>(); 108 test_aligned<OverAligned>(); 109 test_aligned<OverAligned * 2>(); 110 111 return 0; 112 } 113