Clang Project

clang_source_code/test/CXX/special/class.temporary/p6.cpp
1// RUN: %clang_cc1 -std=c++17 %s -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s --implicit-check-not='call{{.*}}dtor'
2
3namespace std {
4  typedef decltype(sizeof(int)) size_t;
5
6  template <class E>
7  struct initializer_list {
8    const E *begin;
9    size_t   size;
10    initializer_list() : begin(nullptr), size(0) {}
11  };
12}
13
14void then();
15
16struct dtor {
17  ~dtor();
18};
19
20dtor ctor();
21
22auto &&lambda = [a = {ctor()}] {};
23// CHECK-LABEL: define
24// CHECK: call {{.*}}ctor
25// CHECK: call {{.*}}atexit{{.*}}global_array_dtor
26
27// CHECK-LABEL: define{{.*}}global_array_dtor
28// CHECK: call {{.*}}dtor
29
30// [lifetime extension occurs if the object was obtained by]
31//  -- a temporary materialization conversion
32// CHECK-LABEL: ref_binding
33void ref_binding() {
34  // CHECK: call {{.*}}ctor
35  auto &&x = ctor();
36  // CHECK: call {{.*}}then
37  then();
38  // CHECK: call {{.*}}dtor
39  // CHECK: }
40}
41
42//  -- ( expression )
43// CHECK-LABEL: parens
44void parens() {
45  // CHECK: call {{.*}}ctor
46  auto &&x = ctor();
47  // CHECK: call {{.*}}then
48  then();
49  // CHECK: call {{.*}}dtor
50  // CHECK: }
51}
52
53//  -- subscripting of an array
54// CHECK-LABEL: array_subscript_1
55void array_subscript_1() {
56  using T = dtor[1];
57  // CHECK: call {{.*}}ctor
58  auto &&x = T{ctor()}[0];
59  // CHECK: call {{.*}}then
60  then();
61  // CHECK: call {{.*}}dtor
62  // CHECK: }
63}
64// CHECK-LABEL: array_subscript_2
65void array_subscript_2() {
66  using T = dtor[1];
67  // CHECK: call {{.*}}ctor
68  auto &&x = ((dtor*)T{ctor()})[0];
69  // CHECK: call {{.*}}dtor
70  // CHECK: call {{.*}}then
71  then();
72  // CHECK: }
73}
74
75struct with_member { dtor d; ~with_member(); };
76struct with_ref_member { dtor &&d; ~with_ref_member(); };
77
78//  -- a class member access using the . operator [...]
79// CHECK-LABEL: member_access_1
80void member_access_1() {
81  // CHECK: call {{.*}}ctor
82  auto &&x = with_member{ctor()}.d;
83  // CHECK: call {{.*}}then
84  then();
85  // CHECK: call {{.*}}with_member
86  // CHECK: }
87}
88// CHECK-LABEL: member_access_2
89void member_access_2() {
90  // CHECK: call {{.*}}ctor
91  auto &&x = with_ref_member{ctor()}.d;
92  // CHECK: call {{.*}}with_ref_member
93  // CHECK: call {{.*}}dtor
94  // CHECK: call {{.*}}then
95  then();
96  // CHECK: }
97}
98// CHECK-LABEL: member_access_3
99void member_access_3() {
100  // CHECK: call {{.*}}ctor
101  auto &&x = (&(const with_member&)with_member{ctor()})->d;
102  // CHECK: call {{.*}}with_member
103  // CHECK: call {{.*}}then
104  then();
105  // CHECK: }
106}
107
108//  -- a pointer-to-member operation using the .* operator [...]
109// CHECK-LABEL: member_ptr_access_1
110void member_ptr_access_1() {
111  // CHECK: call {{.*}}ctor
112  auto &&x = with_member{ctor()}.*&with_member::d;
113  // CHECK: call {{.*}}then
114  then();
115  // CHECK: call {{.*}}with_member
116  // CHECK: }
117}
118// CHECK-LABEL: member_ptr_access_2
119void member_ptr_access_2() {
120  // CHECK: call {{.*}}ctor
121  auto &&x = (&(const with_member&)with_member{ctor()})->*&with_member::d;
122  // CHECK: call {{.*}}with_member
123  // CHECK: call {{.*}}then
124  then();
125  // CHECK: }
126}
127
128//  -- a [named] cast [...]
129// CHECK-LABEL: static_cast
130void test_static_cast() {
131  // CHECK: call {{.*}}ctor
132  auto &&x = static_cast<dtor&&>(ctor());
133  // CHECK: call {{.*}}then
134  then();
135  // CHECK: call {{.*}}dtor
136  // CHECK: }
137}
138// CHECK-LABEL: const_cast
139void test_const_cast() {
140  // CHECK: call {{.*}}ctor
141  auto &&x = const_cast<dtor&&>(ctor());
142  // CHECK: call {{.*}}then
143  then();
144  // CHECK: call {{.*}}dtor
145  // CHECK: }
146}
147// CHECK-LABEL: reinterpret_cast
148void test_reinterpret_cast() {
149  // CHECK: call {{.*}}ctor
150  auto &&x = reinterpret_cast<dtor&&>(static_cast<dtor&&>(ctor()));
151  // CHECK: call {{.*}}then
152  then();
153  // CHECK: call {{.*}}dtor
154  // CHECK: }
155}
156// CHECK-LABEL: dynamic_cast
157void test_dynamic_cast() {
158  // CHECK: call {{.*}}ctor
159  auto &&x = dynamic_cast<dtor&&>(ctor());
160  // CHECK: call {{.*}}then
161  then();
162  // CHECK: call {{.*}}dtor
163  // CHECK: }
164}
165
166//  -- [explicit cast notation is defined in terms of the above]
167// CHECK-LABEL: c_style_cast
168void c_style_cast() {
169  // CHECK: call {{.*}}ctor
170  auto &&x = (dtor&&)ctor();
171  // CHECK: call {{.*}}then
172  then();
173  // CHECK: call {{.*}}dtor
174  // CHECK: }
175}
176// CHECK-LABEL: function_style_cast
177void function_style_cast() {
178  // CHECK: call {{.*}}ctor
179  using R = dtor&&;
180  auto &&x = R(ctor());
181  // CHECK: call {{.*}}then
182  then();
183  // CHECK: call {{.*}}dtor
184  // CHECK: }
185}
186
187//  -- a conditional operator
188// CHECK-LABEL: conditional
189void conditional(bool b) {
190  // CHECK: call {{.*}}ctor
191  // CHECK: call {{.*}}ctor
192  auto &&x = b ? (dtor&&)ctor() : (dtor&&)ctor();
193  // CHECK: call {{.*}}then
194  then();
195  // CHECK: call {{.*}}dtor
196  // CHECK: call {{.*}}dtor
197  // CHECK: }
198}
199
200//  -- a comma expression
201// CHECK-LABEL: comma
202void comma() {
203  // CHECK: call {{.*}}ctor
204  auto &&x = (true, (dtor&&)ctor());
205  // CHECK: call {{.*}}then
206  then();
207  // CHECK: call {{.*}}dtor
208  // CHECK: }
209}
210
211
212// This applies recursively: if an object is lifetime-extended and contains a
213// reference, the referent is also extended.
214// CHECK-LABEL: init_capture_ref
215void init_capture_ref() {
216  // CHECK: call {{.*}}ctor
217  auto x = [&a = (const dtor&)ctor()] {};
218  // CHECK: call {{.*}}then
219  then();
220  // CHECK: call {{.*}}dtor
221  // CHECK: }
222}
223// CHECK-LABEL: init_capture_ref_indirect
224void init_capture_ref_indirect() {
225  // CHECK: call {{.*}}ctor
226  auto x = [&a = (const dtor&)ctor()] {};
227  // CHECK: call {{.*}}then
228  then();
229  // CHECK: call {{.*}}dtor
230  // CHECK: }
231}
232// CHECK-LABEL: init_capture_init_list
233void init_capture_init_list() {
234  // CHECK: call {{.*}}ctor
235  auto x = [a = {ctor()}] {};
236  // CHECK: call {{.*}}then
237  then();
238  // CHECK: call {{.*}}dtor
239  // CHECK: }
240}
241