xref: /llvm-project/clang/test/SemaCXX/constructor-initializer.cpp (revision 7ae2d7758f3f7ccab713ec022d01372f17c251d3)
1 // RUN: %clang_cc1 -Wreorder -fsyntax-only -verify %s
2 class A {
3   int m;
4    A() : A::m(17) { } // expected-error {{member initializer 'm' does not name a non-static data member or base class}}
5    A(int);
6 };
7 
8 class B : public A {
9 public:
10   B() : A(), m(1), n(3.14) { }
11 
12 private:
13   int m;
14   float n;
15 };
16 
17 
18 class C : public virtual B {
19 public:
20   C() : B() { }
21 };
22 
23 class D : public C {
24 public:
25   D() : B(), C() { }
26 };
27 
28 class E : public D, public B {
29 public:
30   E() : B(), D() { } // expected-error{{base class initializer 'class B' names both a direct base class and an inherited virtual base class}}
31 };
32 
33 
34 typedef int INT;
35 
36 class F : public B {
37 public:
38   int B;
39 
40   F() : B(17),
41         m(17), // expected-error{{member initializer 'm' does not name a non-static data member or base class}}
42         INT(17) // expected-error{{constructor initializer 'INT' (aka 'int') does not name a class}}
43   {
44   }
45 };
46 
47 class G : A {
48   G() : A(10); // expected-error{{expected '{'}}
49 };
50 
51 void f() : a(242) { } // expected-error{{only constructors take base initializers}}
52 
53 class H : A {
54   H();
55 };
56 
57 H::H() : A(10) { }
58 
59 
60 class  X {};
61 class Y {};
62 
63 struct S : Y, virtual X {
64   S ();
65 };
66 
67 struct Z : S {
68   Z() : X(), S(), E()  {} // expected-error {{type 'class E' is not a direct or virtual base of 'Z'}}
69 };
70 
71 class U {
72   union { int a; char* p; };
73   union { int b; double d; };
74 
75   U() :  a(1), p(0), d(1.0)  {} // expected-error {{multiple initializations given for non-static member 'p'}} \
76                         // expected-note {{previous initialization is here}}
77 };
78 
79 struct V {};
80 struct Base {};
81 struct Base1 {};
82 
83 struct Derived : Base, Base1, virtual V {
84   Derived ();
85 };
86 
87 struct Current : Derived {
88   int Derived;
89   Current() : Derived(1), ::Derived(), // expected-warning {{member 'Derived' will be initialized after}} \
90                                        // expected-note {{base '::Derived'}} \
91                                        // expected-warning {{base class '::Derived' will be initialized after}}
92                           ::Derived::Base(), // expected-error {{type '::Derived::Base' is not a direct or virtual base of 'Current'}}
93                            Derived::Base1(), // expected-error {{type 'Derived::Base1' is not a direct or virtual base of 'Current'}}
94                            Derived::V(), // expected-note {{base 'Derived::V'}}
95                            ::NonExisting(), // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
96                            INT::NonExisting()  {} // expected-error {{expected a class or namespace}} \
97                                                   // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
98 };
99 
100 struct M {              // expected-note 2 {{candidate constructor (the implicit copy constructor)}} \
101                         // expected-note {{declared here}} \
102                         // expected-note {{declared here}}
103   M(int i, int j);      // expected-note 2 {{candidate constructor}}
104 };
105 
106 struct N : M  {
107   N() : M(1),        // expected-error {{no matching constructor for initialization of 'struct M'}}
108         m1(100) {  } // expected-error {{no matching constructor for initialization of 'struct M'}}
109   M m1;
110 };
111 
112 struct P : M  {
113   P()  {  } // expected-error {{base class 'struct M'}} \
114             // expected-error {{member 'm'}}
115   M m; // expected-note {{member is declared here}}
116 };
117 
118 struct Q {
119   Q() : f1(1,2),       // expected-error {{excess elements in scalar initializer}}
120         pf(0.0)  { }   // expected-error {{cannot initialize a member subobject of type 'float *' with an rvalue of type 'double'}}
121   float f1;
122 
123   float *pf;
124 };
125 
126 // A silly class used to demonstrate field-is-uninitialized in constructors with
127 // multiple params.
128 class TwoInOne { TwoInOne(TwoInOne a, TwoInOne b) {} };
129 class InitializeUsingSelfTest {
130   bool A;
131   char* B;
132   int C;
133   TwoInOne D;
134   InitializeUsingSelfTest(int E)
135       : A(A),  // expected-warning {{field is uninitialized when used here}}
136         B((((B)))),  // expected-warning {{field is uninitialized when used here}}
137         C(A && InitializeUsingSelfTest::C),  // expected-warning {{field is uninitialized when used here}}
138         D(D,  // expected-warning {{field is uninitialized when used here}}
139           D) {}  // expected-warning {{field is uninitialized when used here}}
140 };
141 
142 int IntWrapper(int i) { return 0; };
143 class InitializeUsingSelfExceptions {
144   int A;
145   int B;
146   InitializeUsingSelfExceptions(int B)
147       : A(IntWrapper(A)),  // Due to a conservative implementation, we do not report warnings inside function/ctor calls even though it is possible to do so.
148         B(B) {}  // Not a warning; B is a local variable.
149 };
150 
151 class CopyConstructorTest {
152   bool A, B, C;
153   CopyConstructorTest(const CopyConstructorTest& rhs)
154       : A(rhs.A),
155         B(B),  // expected-warning {{field is uninitialized when used here}}
156         C(rhs.C || C) { }  // expected-warning {{field is uninitialized when used here}}
157 };
158 
159 // Make sure we aren't marking default constructors when we shouldn't be.
160 template<typename T>
161 struct NDC {
162   T &ref;
163 
164   NDC() { }
165   NDC(T &ref) : ref(ref) { }
166 };
167 
168 struct X0 : NDC<int> {
169   X0(int &ref) : NDC<int>(ref), ndc(ref) { }
170 
171   NDC<int> ndc;
172 };
173