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)38 struct 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()50 void 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 **)101 int 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