xref: /llvm-project/clang/test/CXX/special/class.init/class.inhctor.init/p1.cpp (revision 96c899449b61b866b583560a49c4627f561336fc)
15179eb78SRichard Smith // RUN: %clang_cc1 -std=c++11 -verify %s
25179eb78SRichard Smith 
35179eb78SRichard Smith namespace std_example {
480a4702dSRichard Smith   struct B1 {
B1std_example::B155179eb78SRichard Smith     B1(int, ...) {}
65179eb78SRichard Smith   };
75179eb78SRichard Smith 
85179eb78SRichard Smith   struct B2 {
B2std_example::B295179eb78SRichard Smith     B2(double) {}
105179eb78SRichard Smith   };
115179eb78SRichard Smith 
125179eb78SRichard Smith   int get();
135179eb78SRichard Smith 
145179eb78SRichard Smith   struct D1 : B1 { // expected-note {{no default constructor}}
155179eb78SRichard Smith     using B1::B1; // inherits B1(int, ...)
165179eb78SRichard Smith     int x;
175179eb78SRichard Smith     int y = get();
185179eb78SRichard Smith   };
195179eb78SRichard Smith 
test()205179eb78SRichard Smith   void test() {
215179eb78SRichard Smith     D1 d(2, 3, 4); // OK: B1 is initialized by calling B1(2, 3, 4),
225179eb78SRichard Smith     // then d.x is default-initialized (no initialization is performed),
235179eb78SRichard Smith     // then d.y is initialized by calling get()
245179eb78SRichard Smith     D1 e; // expected-error {{implicitly-deleted}}
255179eb78SRichard Smith   }
265179eb78SRichard Smith 
275179eb78SRichard Smith   struct D2 : B2 {
2880a4702dSRichard Smith     using B2::B2;
2980a4702dSRichard Smith     B1 b; // expected-note {{constructor inherited by 'D2' is implicitly deleted because field 'b' has no default constructor}}
305179eb78SRichard Smith   };
315179eb78SRichard Smith 
3280a4702dSRichard Smith   D2 f(1.0); // expected-error {{constructor inherited by 'D2' from base class 'B2' is implicitly deleted}}
335179eb78SRichard Smith 
345179eb78SRichard Smith   struct W {
355179eb78SRichard Smith     W(int);
365179eb78SRichard Smith   };
375179eb78SRichard Smith   struct X : virtual W {
385179eb78SRichard Smith     using W::W;
395179eb78SRichard Smith     X() = delete;
405179eb78SRichard Smith   };
415179eb78SRichard Smith   struct Y : X {
425179eb78SRichard Smith     using X::X;
435179eb78SRichard Smith   };
445179eb78SRichard Smith   struct Z : Y, virtual W {
455179eb78SRichard Smith     using Y::Y;
465179eb78SRichard Smith   };
475179eb78SRichard Smith   Z z(0); // OK: initialization of Y does not invoke default constructor of X
485179eb78SRichard Smith 
495179eb78SRichard Smith   template <class T> struct Log : T {
505179eb78SRichard Smith     using T::T; // inherits all constructors from class T
~Logstd_example::Log515179eb78SRichard Smith     ~Log() { /* ... */ }
525179eb78SRichard Smith   };
535179eb78SRichard Smith }
545179eb78SRichard Smith 
555179eb78SRichard Smith namespace vbase {
5680a4702dSRichard Smith   struct V {
575179eb78SRichard Smith     V(int);
585179eb78SRichard Smith   };
595179eb78SRichard Smith 
605179eb78SRichard Smith   struct A : virtual V {
615179eb78SRichard Smith     A() = delete; // expected-note 2{{deleted here}} expected-note {{deleted}}
625179eb78SRichard Smith     using V::V;
635179eb78SRichard Smith   };
6480a4702dSRichard Smith   struct B : virtual V { // expected-note {{no default constructor}}
655179eb78SRichard Smith     B() = delete; // expected-note 2{{deleted here}}
665179eb78SRichard Smith     B(int, int);
675179eb78SRichard Smith     using V::V;
685179eb78SRichard Smith   };
695179eb78SRichard Smith   struct C : B { // expected-note {{deleted default constructor}}
7080a4702dSRichard Smith     using B::B;
715179eb78SRichard Smith   };
7280a4702dSRichard Smith   struct D : A, C { // expected-note {{deleted default constructor}} expected-note {{deleted corresponding constructor}}
735179eb78SRichard Smith     using A::A;
7480a4702dSRichard Smith     using C::C;
755179eb78SRichard Smith   };
765179eb78SRichard Smith 
775179eb78SRichard Smith   A a0; // expected-error {{deleted}}
785179eb78SRichard Smith   A a1(0);
795179eb78SRichard Smith   B b0; // expected-error {{deleted}}
805179eb78SRichard Smith   B b1(0);
815179eb78SRichard Smith   B b2(0, 0);
825179eb78SRichard Smith   C c0; // expected-error {{deleted}}
835179eb78SRichard Smith   C c1(0);
8480a4702dSRichard Smith   C c2(0, 0); // expected-error {{deleted}}
8580a4702dSRichard Smith   D d0; // expected-error {{deleted}}
865179eb78SRichard Smith   D d1(0);
8780a4702dSRichard Smith   D d2(0, 0); // expected-error {{deleted}}
885179eb78SRichard Smith }
895179eb78SRichard Smith 
90a99fa39cSRichard Smith namespace vbase_of_vbase {
91a99fa39cSRichard Smith   struct V { V(int); };
92a99fa39cSRichard Smith   struct W : virtual V { using V::V; };
93a99fa39cSRichard Smith   struct X : virtual W, virtual V { using W::W; };
94a99fa39cSRichard Smith   X x(0);
95a99fa39cSRichard Smith }
96a99fa39cSRichard Smith 
975179eb78SRichard Smith namespace constexpr_init_order {
985179eb78SRichard Smith   struct Param;
995179eb78SRichard Smith   struct A {
1005179eb78SRichard Smith     constexpr A(Param);
1015179eb78SRichard Smith     int a;
1025179eb78SRichard Smith   };
1035179eb78SRichard Smith 
1045179eb78SRichard Smith   struct B : A { B(); using A::A; int b = 2; };
105*96c89944SRichard Smith 
106*96c89944SRichard Smith   // Construct a situation where a value can be observed to change during
107*96c89944SRichard Smith   // constant evaluation in C++11: value-initialization of Wrap2 performs
108*96c89944SRichard Smith   // zero-initialization and then calls the constructor.
109*96c89944SRichard Smith   struct Wrap1 : B { constexpr Wrap1(); };
110*96c89944SRichard Smith   struct Wrap2 : Wrap1 {};
111*96c89944SRichard Smith 
112*96c89944SRichard Smith   extern const Wrap2 b;
1135179eb78SRichard Smith 
1145179eb78SRichard Smith   struct Param {
Paramconstexpr_init_order::Param1155179eb78SRichard Smith     constexpr Param(int c) : n(4 * b.a + b.b + c) {}
1165179eb78SRichard Smith     int n;
1175179eb78SRichard Smith   };
1185179eb78SRichard Smith 
A(Param p)1195179eb78SRichard Smith   constexpr A::A(Param p) : a(p.n) {}
1205179eb78SRichard Smith 
Wrap1()121*96c89944SRichard Smith   constexpr Wrap1::Wrap1() : B(1) {}
122*96c89944SRichard Smith 
123*96c89944SRichard Smith   constexpr Wrap2 b = {};
1245179eb78SRichard Smith   constexpr B c(1);
1255179eb78SRichard Smith   static_assert(b.a == 1, "p should be initialized before B() is executed");
1262a8c18d9SAlexander Kornienko   static_assert(c.a == 7, "b not initialized properly");
1275179eb78SRichard Smith }
1285179eb78SRichard Smith 
1295179eb78SRichard Smith namespace default_args {
1305179eb78SRichard Smith   // We work around a defect in P0136R1 where it would reject reasonable
1315179eb78SRichard Smith   // code like the following:
1325179eb78SRichard Smith   struct Base {
1335179eb78SRichard Smith     Base(int = 0);
1345179eb78SRichard Smith   };
1355179eb78SRichard Smith   struct Derived : Base {
1365179eb78SRichard Smith     using Base::Base;
1375179eb78SRichard Smith   };
1385179eb78SRichard Smith   Derived d;
1395179eb78SRichard Smith   // FIXME: Once a fix is standardized, implement it.
1405179eb78SRichard Smith }
141