]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/testsuite/20_util/shared_ptr/creation/overwrite.cc
libstdc++: Disable hosted-only tests [PR103626]
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 20_util / shared_ptr / creation / overwrite.cc
CommitLineData
9a0b518a
JW
1// { dg-options "-std=gnu++20 -fno-lifetime-dse -O0" }
2// { dg-do run { target c++20 } }
7cc9022f 3// { dg-require-effective-target hosted }
9a0b518a
JW
4
5// C++20 20.11.3.7 shared_ptr Creation [util.smartptr.shared.create]
6
7#include <memory>
8
9#ifndef __cpp_lib_smart_ptr_for_overwrite
10# error "Feature-test macro for make_shared_for_overwrite missing in <memory>"
11#elif __cpp_lib_smart_ptr_for_overwrite < 202002L
12# error "Feature-test macro for make_shared_for_overwrite has wrong value in <memory>"
13#endif
14
15#include <cstring>
16#include <testsuite_hooks.h>
17
18int counter = 0;
19
20template<typename T>
21struct Alloc : std::allocator<T>
22{
23 Alloc() = default;
24
25 template<typename U>
26 Alloc(const Alloc<U>&) { }
27
28 T* allocate(std::size_t n)
29 {
30 ++counter;
31 void* p = std::allocator<T>::allocate(n);
32 // need -fno-lifetime-dse to check for these values later.
33 std::memset(p, 0xff, n * sizeof(T));
34 return (T*)p;
35 }
36
37 void construct(auto*, auto&&...)
38 {
39 // The objects must be default-initialized, not using this function.
40 VERIFY( ! "allocator_traits::construct" );
41 }
42
43 void destroy(auto*)
44 {
45 // The objects must be destroyed by ~T(), not using this function.
46 VERIFY( ! "allocator_traits::destroy" );
47 }
48};
49
50void
51test01()
52{
53 Alloc<int> a;
54 const int expected = 0xffffffff;
55
56 std::shared_ptr<int> p1 = std::allocate_shared_for_overwrite<int>(a);
57 VERIFY( counter == 1 );
58 VERIFY( *p1 == expected );
59 std::shared_ptr<int[44]> p2 = std::allocate_shared_for_overwrite<int[44]>(a);
60 VERIFY( counter == 2 );
61 VERIFY( p2[0] == expected );
62 p2.reset();
63 std::shared_ptr<int[]> p3 = std::allocate_shared_for_overwrite<int[]>(a, 88);
64 VERIFY( counter == 3 );
65 VERIFY( p3[0] == expected );
66 VERIFY( p3[87] == expected );
67 std::shared_ptr<int[3][4]> p4 = std::allocate_shared_for_overwrite<int[3][4]>(a);
68 VERIFY( counter == 4 );
69 VERIFY( p4[0][0] == expected );
70 VERIFY( p4[2][3] == expected );
71 std::shared_ptr<int[][5]> p5 = std::allocate_shared_for_overwrite<int[][5]>(a, 6);
72 VERIFY( counter == 5 );
73 VERIFY( p5[0][0] == expected );
74 VERIFY( p5[5][4] == expected );
75
76 struct BigBoi { int x[100]; };
77 std::shared_ptr<BigBoi> p6 = std::allocate_shared_for_overwrite<BigBoi>(a);
78 VERIFY( counter == 6 );
79 VERIFY( p6->x[0] == expected );
80 std::shared_ptr<BigBoi[22]> p7 = std::allocate_shared_for_overwrite<BigBoi[22]>(a);
81 VERIFY( counter == 7 );
82 VERIFY( p7[0].x[0] == expected );
83 VERIFY( p7[21].x[99] == expected );
84 std::shared_ptr<BigBoi[]> p8 = std::allocate_shared_for_overwrite<BigBoi[]>(a, 11);
85 VERIFY( counter == 8 );
86 VERIFY( p8[0].x[0] == expected );
87 VERIFY( p8[10].x[10] == expected );
88}
89
90void
91test02()
92{
93 // These aren't created by the custom allocator, so we can't check that the
94 // memory was left uninitialized. Just dereference them.
95
96 std::shared_ptr<int> p1 = std::make_shared_for_overwrite<int>();
97 (void) *p1;
98 std::shared_ptr<int[44]> p2 = std::make_shared_for_overwrite<int[44]>();
99 (void) p2[0];
100 std::shared_ptr<int[]> p3 = std::make_shared_for_overwrite<int[]>(88);
101 (void) p3[0];
102 (void) p3[87];
103 std::shared_ptr<int[3][4]> p4 = std::make_shared_for_overwrite<int[3][4]>();
104 (void) p4[0][0];
105 (void) p4[2][3];
106 std::shared_ptr<int[][5]> p5 = std::make_shared_for_overwrite<int[][5]>(6);
107 (void) p5[0][0];
108 (void) p5[5][4];
109
110 struct BigBoi { int x[100]; };
111 std::shared_ptr<BigBoi> p6 = std::make_shared_for_overwrite<BigBoi>();
112 (void) p6->x[0];
113 std::shared_ptr<BigBoi[22]> p7 = std::make_shared_for_overwrite<BigBoi[22]>();
114 (void) p7[0].x[0];
115 (void) p7[21].x[99];
116 std::shared_ptr<BigBoi[]> p8 = std::make_shared_for_overwrite<BigBoi[]>(11);
117 (void) p8[0].x[0];
118 (void) p8[10].x[10];
119}
120
121void
122test03()
123{
124 // Type with non-trivial initialization should still be default-initialized.
125 struct NonTriv
126 {
127 int init = 0xbb;
128 int uninit;
129 };
130 std::shared_ptr<NonTriv> a = std::make_shared_for_overwrite<NonTriv>();
131 VERIFY( a->init == 0xbb );
132 std::shared_ptr<NonTriv[]> b = std::make_shared_for_overwrite<NonTriv[2]>();
133 VERIFY( b[1].init == 0xbb );
134 std::shared_ptr<NonTriv[]> c = std::make_shared_for_overwrite<NonTriv[]>(2);
135 VERIFY( c[1].init == 0xbb );
136}
137
138int
139main()
140{
141 test01();
142 test02();
143 test03();
144}