xref: /minix3/external/bsd/llvm/dist/clang/test/CXX/special/class.copy/implicit-move.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
2f4a2713aSLionel Sambuc 
3f4a2713aSLionel Sambuc // Tests for implicit (non-)declaration of move constructor and
4f4a2713aSLionel Sambuc // assignment: p9, p11, p20, p23.
5f4a2713aSLionel Sambuc 
6f4a2713aSLionel Sambuc // This class, used as a member, allows to distinguish move from copy because
7f4a2713aSLionel Sambuc // move operations are no-throw, copy operations aren't.
8f4a2713aSLionel Sambuc struct ThrowingCopy {
9f4a2713aSLionel Sambuc   ThrowingCopy() noexcept;
10f4a2713aSLionel Sambuc   ThrowingCopy(ThrowingCopy &&) noexcept;
11f4a2713aSLionel Sambuc   ThrowingCopy(const ThrowingCopy &) noexcept(false);
12f4a2713aSLionel Sambuc   ThrowingCopy & operator =(ThrowingCopy &&) noexcept;
13f4a2713aSLionel Sambuc   ThrowingCopy & operator =(const ThrowingCopy &) noexcept(false);
14f4a2713aSLionel Sambuc };
15f4a2713aSLionel Sambuc 
16f4a2713aSLionel Sambuc struct HasCopyConstructor {
17f4a2713aSLionel Sambuc   ThrowingCopy tc;
18f4a2713aSLionel Sambuc   HasCopyConstructor() noexcept;
19f4a2713aSLionel Sambuc   HasCopyConstructor(const HasCopyConstructor &) noexcept(false);
20f4a2713aSLionel Sambuc };
21f4a2713aSLionel Sambuc 
22f4a2713aSLionel Sambuc struct HasCopyAssignment {
23f4a2713aSLionel Sambuc   ThrowingCopy tc;
24f4a2713aSLionel Sambuc   HasCopyAssignment() noexcept;
25f4a2713aSLionel Sambuc   HasCopyAssignment & operator =(const HasCopyAssignment &) noexcept(false);
26f4a2713aSLionel Sambuc };
27f4a2713aSLionel Sambuc 
28f4a2713aSLionel Sambuc struct HasMoveConstructor {
29f4a2713aSLionel Sambuc   ThrowingCopy tc;
30f4a2713aSLionel Sambuc   HasMoveConstructor() noexcept;
31f4a2713aSLionel Sambuc   HasMoveConstructor(HasMoveConstructor &&) noexcept; // expected-note {{copy assignment operator is implicitly deleted because 'HasMoveConstructor' has a user-declared move constructor}}
32f4a2713aSLionel Sambuc };
33f4a2713aSLionel Sambuc 
34f4a2713aSLionel Sambuc struct HasMoveAssignment { // expected-note {{implicit copy constructor}}
35f4a2713aSLionel Sambuc   ThrowingCopy tc;
36f4a2713aSLionel Sambuc   HasMoveAssignment() noexcept;
37f4a2713aSLionel Sambuc   HasMoveAssignment & operator =(HasMoveAssignment &&) noexcept;
38f4a2713aSLionel Sambuc };
39f4a2713aSLionel Sambuc 
40f4a2713aSLionel Sambuc struct HasDestructor {
41f4a2713aSLionel Sambuc   ThrowingCopy tc;
42f4a2713aSLionel Sambuc   HasDestructor() noexcept;
43f4a2713aSLionel Sambuc   ~HasDestructor() noexcept;
44f4a2713aSLionel Sambuc };
45f4a2713aSLionel Sambuc 
test_basic_exclusion()46f4a2713aSLionel Sambuc void test_basic_exclusion() {
47f4a2713aSLionel Sambuc   static_assert(!noexcept(HasCopyConstructor((HasCopyConstructor()))), "");
48f4a2713aSLionel Sambuc   HasCopyConstructor hcc;
49f4a2713aSLionel Sambuc   static_assert(!noexcept(hcc = HasCopyConstructor()), "");
50f4a2713aSLionel Sambuc 
51f4a2713aSLionel Sambuc   static_assert(!noexcept(HasCopyAssignment((HasCopyAssignment()))), "");
52f4a2713aSLionel Sambuc   HasCopyAssignment hca;
53f4a2713aSLionel Sambuc   static_assert(!noexcept(hca = HasCopyAssignment()), "");
54f4a2713aSLionel Sambuc 
55f4a2713aSLionel Sambuc   static_assert(noexcept(HasMoveConstructor((HasMoveConstructor()))), "");
56f4a2713aSLionel Sambuc   HasMoveConstructor hmc;
57f4a2713aSLionel Sambuc   hmc = HasMoveConstructor(); // expected-error {{object of type 'HasMoveConstructor' cannot be assigned because its copy assignment operator is implicitly deleted}}
58f4a2713aSLionel Sambuc 
59f4a2713aSLionel Sambuc   (HasMoveAssignment(HasMoveAssignment())); // expected-error {{uses deleted function}}
60f4a2713aSLionel Sambuc   HasMoveAssignment hma;
61f4a2713aSLionel Sambuc   static_assert(noexcept(hma = HasMoveAssignment()), "");
62f4a2713aSLionel Sambuc 
63f4a2713aSLionel Sambuc   static_assert(!noexcept(HasDestructor((HasDestructor()))), "");
64f4a2713aSLionel Sambuc   HasDestructor hd;
65f4a2713aSLionel Sambuc   static_assert(!noexcept(hd = HasDestructor()), "");
66f4a2713aSLionel Sambuc }
67f4a2713aSLionel Sambuc 
68f4a2713aSLionel Sambuc struct PrivateMove {
69f4a2713aSLionel Sambuc   PrivateMove() noexcept;
70f4a2713aSLionel Sambuc   PrivateMove(const PrivateMove &) noexcept(false);
71f4a2713aSLionel Sambuc   PrivateMove & operator =(const PrivateMove &) noexcept(false);
72f4a2713aSLionel Sambuc private:
73f4a2713aSLionel Sambuc   PrivateMove(PrivateMove &&) noexcept;
74f4a2713aSLionel Sambuc   PrivateMove & operator =(PrivateMove &&) noexcept;
75f4a2713aSLionel Sambuc };
76f4a2713aSLionel Sambuc 
77f4a2713aSLionel Sambuc struct InheritsPrivateMove : PrivateMove {};
78f4a2713aSLionel Sambuc struct ContainsPrivateMove {
79f4a2713aSLionel Sambuc   PrivateMove pm;
80f4a2713aSLionel Sambuc };
81f4a2713aSLionel Sambuc 
82f4a2713aSLionel Sambuc struct PrivateDestructor {
83f4a2713aSLionel Sambuc   PrivateDestructor() noexcept;
84f4a2713aSLionel Sambuc   PrivateDestructor(const PrivateDestructor &) noexcept(false);
85f4a2713aSLionel Sambuc   PrivateDestructor(PrivateDestructor &&) noexcept;
86f4a2713aSLionel Sambuc private:
87f4a2713aSLionel Sambuc   ~PrivateDestructor() noexcept;
88f4a2713aSLionel Sambuc };
89f4a2713aSLionel Sambuc 
90f4a2713aSLionel Sambuc struct InheritsPrivateDestructor : PrivateDestructor {}; // expected-note{{base class 'PrivateDestructor' has an inaccessible destructor}}
91f4a2713aSLionel Sambuc struct ContainsPrivateDestructor {
92f4a2713aSLionel Sambuc   PrivateDestructor pd; // expected-note{{field 'pd' has an inaccessible destructor}}
93f4a2713aSLionel Sambuc };
94f4a2713aSLionel Sambuc 
95f4a2713aSLionel Sambuc struct NonTrivialCopyOnly {
96f4a2713aSLionel Sambuc   NonTrivialCopyOnly() noexcept;
97f4a2713aSLionel Sambuc   NonTrivialCopyOnly(const NonTrivialCopyOnly &) noexcept(false);
98f4a2713aSLionel Sambuc   NonTrivialCopyOnly & operator =(const NonTrivialCopyOnly &) noexcept(false);
99f4a2713aSLionel Sambuc };
100f4a2713aSLionel Sambuc 
101f4a2713aSLionel Sambuc struct InheritsNonTrivialCopyOnly : NonTrivialCopyOnly {};
102f4a2713aSLionel Sambuc struct ContainsNonTrivialCopyOnly {
103f4a2713aSLionel Sambuc   NonTrivialCopyOnly ntco;
104f4a2713aSLionel Sambuc };
105f4a2713aSLionel Sambuc 
106f4a2713aSLionel Sambuc struct ContainsConst {
107f4a2713aSLionel Sambuc   const int i;
108f4a2713aSLionel Sambuc   ContainsConst() noexcept;
109f4a2713aSLionel Sambuc   ContainsConst & operator =(ContainsConst &); // expected-note {{not viable}}
110f4a2713aSLionel Sambuc };
111f4a2713aSLionel Sambuc 
112f4a2713aSLionel Sambuc struct ContainsRef {
113f4a2713aSLionel Sambuc   int &i;
114f4a2713aSLionel Sambuc   ContainsRef() noexcept;
115f4a2713aSLionel Sambuc   ContainsRef & operator =(ContainsRef &); // expected-note {{not viable}}
116f4a2713aSLionel Sambuc };
117f4a2713aSLionel Sambuc 
118f4a2713aSLionel Sambuc struct Base {
119f4a2713aSLionel Sambuc   Base & operator =(Base &);
120f4a2713aSLionel Sambuc };
121f4a2713aSLionel Sambuc struct DirectVirtualBase : virtual Base {}; // expected-note {{copy assignment operator) not viable}}
122f4a2713aSLionel Sambuc struct IndirectVirtualBase : DirectVirtualBase {}; // expected-note {{copy assignment operator) not viable}}
123f4a2713aSLionel Sambuc 
test_deletion_exclusion()124f4a2713aSLionel Sambuc void test_deletion_exclusion() {
125f4a2713aSLionel Sambuc   // FIXME: How to test the union thing?
126f4a2713aSLionel Sambuc 
127f4a2713aSLionel Sambuc   static_assert(!noexcept(InheritsPrivateMove(InheritsPrivateMove())), "");
128f4a2713aSLionel Sambuc   static_assert(!noexcept(ContainsPrivateMove(ContainsPrivateMove())), "");
129f4a2713aSLionel Sambuc   InheritsPrivateMove ipm;
130f4a2713aSLionel Sambuc   static_assert(!noexcept(ipm = InheritsPrivateMove()), "");
131f4a2713aSLionel Sambuc   ContainsPrivateMove cpm;
132f4a2713aSLionel Sambuc   static_assert(!noexcept(cpm = ContainsPrivateMove()), "");
133f4a2713aSLionel Sambuc 
134f4a2713aSLionel Sambuc   (InheritsPrivateDestructor(InheritsPrivateDestructor())); // expected-error {{call to implicitly-deleted default constructor}}
135f4a2713aSLionel Sambuc   (ContainsPrivateDestructor(ContainsPrivateDestructor())); // expected-error {{call to implicitly-deleted default constructor}}
136f4a2713aSLionel Sambuc 
137f4a2713aSLionel Sambuc   static_assert(!noexcept(InheritsNonTrivialCopyOnly(InheritsNonTrivialCopyOnly())), "");
138f4a2713aSLionel Sambuc   static_assert(!noexcept(ContainsNonTrivialCopyOnly(ContainsNonTrivialCopyOnly())), "");
139f4a2713aSLionel Sambuc   InheritsNonTrivialCopyOnly intco;
140f4a2713aSLionel Sambuc   static_assert(!noexcept(intco = InheritsNonTrivialCopyOnly()), "");
141f4a2713aSLionel Sambuc   ContainsNonTrivialCopyOnly cntco;
142f4a2713aSLionel Sambuc   static_assert(!noexcept(cntco = ContainsNonTrivialCopyOnly()), "");
143f4a2713aSLionel Sambuc 
144f4a2713aSLionel Sambuc   ContainsConst cc;
145f4a2713aSLionel Sambuc   cc = ContainsConst(); // expected-error {{no viable}}
146f4a2713aSLionel Sambuc 
147f4a2713aSLionel Sambuc   ContainsRef cr;
148f4a2713aSLionel Sambuc   cr = ContainsRef(); // expected-error {{no viable}}
149f4a2713aSLionel Sambuc 
150f4a2713aSLionel Sambuc   DirectVirtualBase dvb;
151f4a2713aSLionel Sambuc   dvb = DirectVirtualBase(); // expected-error {{no viable}}
152f4a2713aSLionel Sambuc 
153f4a2713aSLionel Sambuc   IndirectVirtualBase ivb;
154f4a2713aSLionel Sambuc   ivb = IndirectVirtualBase(); // expected-error {{no viable}}
155f4a2713aSLionel Sambuc }
156f4a2713aSLionel Sambuc 
157f4a2713aSLionel Sambuc struct ContainsRValueRef {
158f4a2713aSLionel Sambuc   int&& ri;
159f4a2713aSLionel Sambuc   ContainsRValueRef() noexcept;
160f4a2713aSLionel Sambuc };
161f4a2713aSLionel Sambuc 
test_contains_rref()162f4a2713aSLionel Sambuc void test_contains_rref() {
163f4a2713aSLionel Sambuc   (ContainsRValueRef(ContainsRValueRef()));
164f4a2713aSLionel Sambuc }
165f4a2713aSLionel Sambuc 
166f4a2713aSLionel Sambuc 
167f4a2713aSLionel Sambuc namespace DR1402 {
168f4a2713aSLionel Sambuc   struct NonTrivialCopyCtor {
169f4a2713aSLionel Sambuc     NonTrivialCopyCtor(const NonTrivialCopyCtor &);
170f4a2713aSLionel Sambuc   };
171f4a2713aSLionel Sambuc   struct NonTrivialCopyAssign {
172f4a2713aSLionel Sambuc     NonTrivialCopyAssign &operator=(const NonTrivialCopyAssign &);
173f4a2713aSLionel Sambuc   };
174f4a2713aSLionel Sambuc 
175f4a2713aSLionel Sambuc   struct NonTrivialCopyCtorVBase : virtual NonTrivialCopyCtor {
176f4a2713aSLionel Sambuc     NonTrivialCopyCtorVBase(NonTrivialCopyCtorVBase &&);
177f4a2713aSLionel Sambuc     NonTrivialCopyCtorVBase &operator=(NonTrivialCopyCtorVBase &&) = default;
178f4a2713aSLionel Sambuc   };
179f4a2713aSLionel Sambuc   struct NonTrivialCopyAssignVBase : virtual NonTrivialCopyAssign {
180f4a2713aSLionel Sambuc     NonTrivialCopyAssignVBase(NonTrivialCopyAssignVBase &&);
181f4a2713aSLionel Sambuc     NonTrivialCopyAssignVBase &operator=(NonTrivialCopyAssignVBase &&) = default;
182f4a2713aSLionel Sambuc   };
183f4a2713aSLionel Sambuc 
184f4a2713aSLionel Sambuc   struct NonTrivialMoveAssign {
185f4a2713aSLionel Sambuc     NonTrivialMoveAssign(NonTrivialMoveAssign&&);
186f4a2713aSLionel Sambuc     NonTrivialMoveAssign &operator=(NonTrivialMoveAssign &&);
187f4a2713aSLionel Sambuc   };
188f4a2713aSLionel Sambuc   struct NonTrivialMoveAssignVBase : virtual NonTrivialMoveAssign {
189f4a2713aSLionel Sambuc     NonTrivialMoveAssignVBase(NonTrivialMoveAssignVBase &&);
190f4a2713aSLionel Sambuc     NonTrivialMoveAssignVBase &operator=(NonTrivialMoveAssignVBase &&) = default;
191f4a2713aSLionel Sambuc   };
192f4a2713aSLionel Sambuc 
193f4a2713aSLionel Sambuc   // DR1402: A non-movable, non-trivially-copyable class type as a subobject no
194f4a2713aSLionel Sambuc   // longer inhibits the declaration of a move operation.
195f4a2713aSLionel Sambuc   struct NoMove1 { NonTrivialCopyCtor ntcc; };
196f4a2713aSLionel Sambuc   struct NoMove2 { NonTrivialCopyAssign ntcc; };
197f4a2713aSLionel Sambuc   struct NoMove3 : NonTrivialCopyCtor {};
198f4a2713aSLionel Sambuc   struct NoMove4 : NonTrivialCopyAssign {};
199f4a2713aSLionel Sambuc   struct NoMove5 : virtual NonTrivialCopyCtor {};
200f4a2713aSLionel Sambuc   struct NoMove6 : virtual NonTrivialCopyAssign {};
201f4a2713aSLionel Sambuc   struct NoMove7 : NonTrivialCopyCtorVBase {};
202f4a2713aSLionel Sambuc   struct NoMove8 : NonTrivialCopyAssignVBase {};
203f4a2713aSLionel Sambuc 
204f4a2713aSLionel Sambuc   // DR1402: A non-trivially-move-assignable virtual base class no longer
205f4a2713aSLionel Sambuc   // inhibits the declaration of a move assignment (even though it might
206f4a2713aSLionel Sambuc   // move-assign the base class multiple times).
207f4a2713aSLionel Sambuc   struct NoMove9 : NonTrivialMoveAssign {};
208f4a2713aSLionel Sambuc   struct NoMove10 : virtual NonTrivialMoveAssign {};
209f4a2713aSLionel Sambuc   struct NoMove11 : NonTrivialMoveAssignVBase {};
210f4a2713aSLionel Sambuc 
test(T t)211f4a2713aSLionel Sambuc   template<typename T> void test(T t) {
212f4a2713aSLionel Sambuc     (void)T(static_cast<T&&>(t)); // ok
213f4a2713aSLionel Sambuc     t = static_cast<T&&>(t); // ok
214f4a2713aSLionel Sambuc   }
215f4a2713aSLionel Sambuc   template void test(NoMove1);
216f4a2713aSLionel Sambuc   template void test(NoMove2);
217f4a2713aSLionel Sambuc   template void test(NoMove3);
218f4a2713aSLionel Sambuc   template void test(NoMove4);
219f4a2713aSLionel Sambuc   template void test(NoMove5);
220f4a2713aSLionel Sambuc   template void test(NoMove6);
221f4a2713aSLionel Sambuc   template void test(NoMove7);
222f4a2713aSLionel Sambuc   template void test(NoMove8);
223f4a2713aSLionel Sambuc   template void test(NoMove9);
224f4a2713aSLionel Sambuc   template void test(NoMove10);
225f4a2713aSLionel Sambuc   template void test(NoMove11);
226f4a2713aSLionel Sambuc 
227f4a2713aSLionel Sambuc   struct CopyOnly {
228f4a2713aSLionel Sambuc     CopyOnly(const CopyOnly&);
229f4a2713aSLionel Sambuc     CopyOnly &operator=(const CopyOnly&);
230f4a2713aSLionel Sambuc   };
231f4a2713aSLionel Sambuc   struct MoveOnly {
232f4a2713aSLionel Sambuc     MoveOnly(MoveOnly&&); // expected-note {{user-declared move}}
233f4a2713aSLionel Sambuc     MoveOnly &operator=(MoveOnly&&);
234f4a2713aSLionel Sambuc   };
235f4a2713aSLionel Sambuc   template void test(CopyOnly); // ok, copies
236f4a2713aSLionel Sambuc   template void test(MoveOnly); // ok, moves
237f4a2713aSLionel Sambuc   struct CopyAndMove { // expected-note {{implicitly deleted}}
238f4a2713aSLionel Sambuc     CopyOnly co;
239f4a2713aSLionel Sambuc     MoveOnly mo; // expected-note {{deleted copy}}
240f4a2713aSLionel Sambuc   };
241f4a2713aSLionel Sambuc   template void test(CopyAndMove); // ok, copies co, moves mo
test2(CopyAndMove cm)242f4a2713aSLionel Sambuc   void test2(CopyAndMove cm) {
243f4a2713aSLionel Sambuc     (void)CopyAndMove(cm); // expected-error {{deleted}}
244f4a2713aSLionel Sambuc     cm = cm; // expected-error {{deleted}}
245f4a2713aSLionel Sambuc   }
246f4a2713aSLionel Sambuc 
247f4a2713aSLionel Sambuc   namespace VbaseMove {
248f4a2713aSLionel Sambuc     struct A {};
249f4a2713aSLionel Sambuc     struct B { B &operator=(B&&); };
250f4a2713aSLionel Sambuc     struct C { C &operator=(const C&); };
251f4a2713aSLionel Sambuc     struct D { B b; };
252f4a2713aSLionel Sambuc 
253f4a2713aSLionel Sambuc     template<typename T, unsigned I, bool NonTrivialMove = false>
254f4a2713aSLionel Sambuc     struct E : virtual T {};
255f4a2713aSLionel Sambuc 
256f4a2713aSLionel Sambuc     template<typename T, unsigned I>
257f4a2713aSLionel Sambuc     struct E<T, I, true> : virtual T { E &operator=(E&&); };
258f4a2713aSLionel Sambuc 
259f4a2713aSLionel Sambuc     template<typename T>
260f4a2713aSLionel Sambuc     struct F :
261*0a6a1f1dSLionel Sambuc       E<T, 0>, // expected-note-re 2{{'{{[BD]}}' is a virtual base class of base class 'E<}}
262*0a6a1f1dSLionel Sambuc       E<T, 1> {}; // expected-note-re 2{{'{{[BD]}}' is a virtual base class of base class 'E<}}
263f4a2713aSLionel Sambuc 
264f4a2713aSLionel Sambuc     template<typename T>
265f4a2713aSLionel Sambuc     struct G : E<T, 0, true>, E<T, 0> {};
266f4a2713aSLionel Sambuc 
267f4a2713aSLionel Sambuc     template<typename T>
268f4a2713aSLionel Sambuc     struct H : E<T, 0, true>, E<T, 1, true> {};
269f4a2713aSLionel Sambuc 
270f4a2713aSLionel Sambuc     template<typename T>
271f4a2713aSLionel Sambuc     struct I : E<T, 0>, T {};
272f4a2713aSLionel Sambuc 
273f4a2713aSLionel Sambuc     template<typename T>
274f4a2713aSLionel Sambuc     struct J :
275*0a6a1f1dSLionel Sambuc       E<T, 0>, // expected-note-re 2{{'{{[BD]}}' is a virtual base class of base class 'E<}}
276*0a6a1f1dSLionel Sambuc       virtual T {}; // expected-note-re 2{{virtual base class '{{[BD]}}' declared here}}
277f4a2713aSLionel Sambuc 
move(T t)278f4a2713aSLionel Sambuc     template<typename T> void move(T t) { t = static_cast<T&&>(t); }
279*0a6a1f1dSLionel Sambuc     // expected-warning-re@-1 4{{defaulted move assignment operator of {{.*}} will move assign virtual base class '{{[BD]}}' multiple times}}
280f4a2713aSLionel Sambuc     template void move(F<A>);
281f4a2713aSLionel Sambuc     template void move(F<B>); // expected-note {{in instantiation of}}
282f4a2713aSLionel Sambuc     template void move(F<C>);
283f4a2713aSLionel Sambuc     template void move(F<D>); // expected-note {{in instantiation of}}
284f4a2713aSLionel Sambuc     template void move(G<A>);
285f4a2713aSLionel Sambuc     template void move(G<B>);
286f4a2713aSLionel Sambuc     template void move(G<C>);
287f4a2713aSLionel Sambuc     template void move(G<D>);
288f4a2713aSLionel Sambuc     template void move(H<A>);
289f4a2713aSLionel Sambuc     template void move(H<B>);
290f4a2713aSLionel Sambuc     template void move(H<C>);
291f4a2713aSLionel Sambuc     template void move(H<D>);
292f4a2713aSLionel Sambuc     template void move(I<A>);
293f4a2713aSLionel Sambuc     template void move(I<B>);
294f4a2713aSLionel Sambuc     template void move(I<C>);
295f4a2713aSLionel Sambuc     template void move(I<D>);
296f4a2713aSLionel Sambuc     template void move(J<A>);
297f4a2713aSLionel Sambuc     template void move(J<B>); // expected-note {{in instantiation of}}
298f4a2713aSLionel Sambuc     template void move(J<C>);
299f4a2713aSLionel Sambuc     template void move(J<D>); // expected-note {{in instantiation of}}
300f4a2713aSLionel Sambuc   }
301f4a2713aSLionel Sambuc }
302f4a2713aSLionel Sambuc 
303f4a2713aSLionel Sambuc namespace PR12625 {
304f4a2713aSLionel Sambuc   struct X; // expected-note {{forward decl}}
305f4a2713aSLionel Sambuc   struct Y {
306f4a2713aSLionel Sambuc     X x; // expected-error {{incomplete}}
307f4a2713aSLionel Sambuc   } y = Y();
308f4a2713aSLionel Sambuc }
309