xref: /llvm-project/clang/test/CXX/special/class.init/class.inhctor.init/p1.cpp (revision 96c899449b61b866b583560a49c4627f561336fc)
1 // RUN: %clang_cc1 -std=c++11 -verify %s
2 
3 namespace std_example {
4   struct B1 {
B1std_example::B15     B1(int, ...) {}
6   };
7 
8   struct B2 {
B2std_example::B29     B2(double) {}
10   };
11 
12   int get();
13 
14   struct D1 : B1 { // expected-note {{no default constructor}}
15     using B1::B1; // inherits B1(int, ...)
16     int x;
17     int y = get();
18   };
19 
test()20   void test() {
21     D1 d(2, 3, 4); // OK: B1 is initialized by calling B1(2, 3, 4),
22     // then d.x is default-initialized (no initialization is performed),
23     // then d.y is initialized by calling get()
24     D1 e; // expected-error {{implicitly-deleted}}
25   }
26 
27   struct D2 : B2 {
28     using B2::B2;
29     B1 b; // expected-note {{constructor inherited by 'D2' is implicitly deleted because field 'b' has no default constructor}}
30   };
31 
32   D2 f(1.0); // expected-error {{constructor inherited by 'D2' from base class 'B2' is implicitly deleted}}
33 
34   struct W {
35     W(int);
36   };
37   struct X : virtual W {
38     using W::W;
39     X() = delete;
40   };
41   struct Y : X {
42     using X::X;
43   };
44   struct Z : Y, virtual W {
45     using Y::Y;
46   };
47   Z z(0); // OK: initialization of Y does not invoke default constructor of X
48 
49   template <class T> struct Log : T {
50     using T::T; // inherits all constructors from class T
~Logstd_example::Log51     ~Log() { /* ... */ }
52   };
53 }
54 
55 namespace vbase {
56   struct V {
57     V(int);
58   };
59 
60   struct A : virtual V {
61     A() = delete; // expected-note 2{{deleted here}} expected-note {{deleted}}
62     using V::V;
63   };
64   struct B : virtual V { // expected-note {{no default constructor}}
65     B() = delete; // expected-note 2{{deleted here}}
66     B(int, int);
67     using V::V;
68   };
69   struct C : B { // expected-note {{deleted default constructor}}
70     using B::B;
71   };
72   struct D : A, C { // expected-note {{deleted default constructor}} expected-note {{deleted corresponding constructor}}
73     using A::A;
74     using C::C;
75   };
76 
77   A a0; // expected-error {{deleted}}
78   A a1(0);
79   B b0; // expected-error {{deleted}}
80   B b1(0);
81   B b2(0, 0);
82   C c0; // expected-error {{deleted}}
83   C c1(0);
84   C c2(0, 0); // expected-error {{deleted}}
85   D d0; // expected-error {{deleted}}
86   D d1(0);
87   D d2(0, 0); // expected-error {{deleted}}
88 }
89 
90 namespace vbase_of_vbase {
91   struct V { V(int); };
92   struct W : virtual V { using V::V; };
93   struct X : virtual W, virtual V { using W::W; };
94   X x(0);
95 }
96 
97 namespace constexpr_init_order {
98   struct Param;
99   struct A {
100     constexpr A(Param);
101     int a;
102   };
103 
104   struct B : A { B(); using A::A; int b = 2; };
105 
106   // Construct a situation where a value can be observed to change during
107   // constant evaluation in C++11: value-initialization of Wrap2 performs
108   // zero-initialization and then calls the constructor.
109   struct Wrap1 : B { constexpr Wrap1(); };
110   struct Wrap2 : Wrap1 {};
111 
112   extern const Wrap2 b;
113 
114   struct Param {
Paramconstexpr_init_order::Param115     constexpr Param(int c) : n(4 * b.a + b.b + c) {}
116     int n;
117   };
118 
A(Param p)119   constexpr A::A(Param p) : a(p.n) {}
120 
Wrap1()121   constexpr Wrap1::Wrap1() : B(1) {}
122 
123   constexpr Wrap2 b = {};
124   constexpr B c(1);
125   static_assert(b.a == 1, "p should be initialized before B() is executed");
126   static_assert(c.a == 7, "b not initialized properly");
127 }
128 
129 namespace default_args {
130   // We work around a defect in P0136R1 where it would reject reasonable
131   // code like the following:
132   struct Base {
133     Base(int = 0);
134   };
135   struct Derived : Base {
136     using Base::Base;
137   };
138   Derived d;
139   // FIXME: Once a fix is standardized, implement it.
140 }
141