xref: /llvm-project/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/incomplete.sh.cpp (revision dfe737f231d7162ea5658df3b97fd71cc39441d8)
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 // unique_ptr
12 
13 // Make sure that we can form unique_ptrs to incomplete types and perform restricted
14 // operations on them. This requires setting up a TU where the type is complete and
15 // the unique_ptr is created and destroyed, and a TU where the type is incomplete and
16 // we check that a restricted set of operations can be performed on the unique_ptr.
17 
18 // RUN: %{cxx} %s %{flags} %{compile_flags} -c -o %t.tu1.o -DCOMPLETE
19 // RUN: %{cxx} %s %{flags} %{compile_flags} -c -o %t.tu2.o -DINCOMPLETE
20 // RUN: %{cxx} %t.tu1.o %t.tu2.o %{flags} %{link_flags} -o %t.exe
21 // RUN: %{exec} %t.exe
22 
23 #include <memory>
24 #include <cassert>
25 
26 struct Foo;
27 extern void use(std::unique_ptr<Foo>& ptr);
28 extern void use(std::unique_ptr<Foo[]>& ptr);
29 
30 #ifdef INCOMPLETE
31 
32 void use(std::unique_ptr<Foo>& ptr) {
33   {
34     Foo* x = ptr.get();
35     assert(x != nullptr);
36   }
37   {
38     Foo& ref = *ptr;
39     assert(&ref == ptr.get());
40   }
41   {
42     bool engaged = static_cast<bool>(ptr);
43     assert(engaged);
44   }
45   {
46     assert(ptr == ptr);
47     assert(!(ptr != ptr));
48     assert(!(ptr < ptr));
49     assert(!(ptr > ptr));
50     assert(ptr <= ptr);
51     assert(ptr >= ptr);
52   }
53 }
54 
55 void use(std::unique_ptr<Foo[]>& ptr) {
56   {
57     Foo* x = ptr.get();
58     assert(x != nullptr);
59   }
60   {
61     bool engaged = static_cast<bool>(ptr);
62     assert(engaged);
63   }
64   {
65     assert(ptr == ptr);
66     assert(!(ptr != ptr));
67     assert(!(ptr < ptr));
68     assert(!(ptr > ptr));
69     assert(ptr <= ptr);
70     assert(ptr >= ptr);
71   }
72 }
73 
74 #endif // INCOMPLETE
75 
76 #ifdef COMPLETE
77 
78 struct Foo {}; // complete the type
79 
80 int main(int, char**) {
81   {
82     std::unique_ptr<Foo> ptr(new Foo());
83     use(ptr);
84   }
85 
86   {
87     std::unique_ptr<Foo[]> ptr(new Foo[3]());
88     use(ptr);
89   }
90   return 0;
91 }
92 
93 #endif // COMPLETE
94