constructor-initializer.cpp revision e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8
1// RUN: %clang_cc1 -Wreorder -fsyntax-only -verify %s
2class A {
3  int m;
4public:
5   A() : A::m(17) { } // expected-error {{member initializer 'm' does not name a non-static data member or base class}}
6   A(int);
7};
8
9class B : public A {
10public:
11  B() : A(), m(1), n(3.14) { }
12
13private:
14  int m;
15  float n;
16};
17
18
19class C : public virtual B {
20public:
21  C() : B() { }
22};
23
24class D : public C {
25public:
26  D() : B(), C() { }
27};
28
29class E : public D, public B {
30public:
31  E() : B(), D() { } // expected-error{{base class initializer 'B' names both a direct base class and an inherited virtual base class}}
32};
33
34
35typedef int INT;
36
37class F : public B {
38public:
39  int B;
40
41  F() : B(17),
42        m(17), // expected-error{{member initializer 'm' does not name a non-static data member or base class}}
43        INT(17) // expected-error{{constructor initializer 'INT' (aka 'int') does not name a class}}
44  {
45  }
46};
47
48class G : A {
49  G() : A(10); // expected-error{{expected '{'}}
50};
51
52void f() : a(242) { } // expected-error{{only constructors take base initializers}}
53
54class H : A {
55  H();
56};
57
58H::H() : A(10) { }
59
60
61class  X {};
62class Y {};
63
64struct S : Y, virtual X {
65  S ();
66};
67
68struct Z : S {
69  Z() : X(), S(), E()  {} // expected-error {{type 'E' is not a direct or virtual base of 'Z'}}
70};
71
72class U {
73  union { int a; char* p; };
74  union { int b; double d; };
75
76  U() :  a(1), // expected-note {{previous initialization is here}}
77         p(0), // expected-error {{initializing multiple members of union}}
78         d(1.0)  {}
79};
80
81struct V {};
82struct Base {};
83struct Base1 {};
84
85struct Derived : Base, Base1, virtual V {
86  Derived ();
87};
88
89struct Current : Derived {
90  int Derived;
91  Current() : Derived(1), ::Derived(), // expected-warning {{field 'Derived' will be initialized after base '::Derived'}} \
92                                       // expected-warning {{base class '::Derived' will be initialized after base 'Derived::V'}}
93                          ::Derived::Base(), // expected-error {{type '::Derived::Base' is not a direct or virtual base of 'Current'}}
94                           Derived::Base1(), // expected-error {{type 'Derived::Base1' is not a direct or virtual base of 'Current'}}
95                           Derived::V(),
96                           ::NonExisting(), // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
97                           INT::NonExisting()  {} // expected-error {{expected a class or namespace}} \
98                                                  // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
99};
100
101struct M {              // expected-note 2 {{candidate constructor (the implicit copy constructor)}} \
102                        // expected-note {{declared here}} \
103                        // expected-note {{declared here}}
104  M(int i, int j);      // expected-note 2 {{candidate constructor}}
105};
106
107struct N : M  {
108  N() : M(1),        // expected-error {{no matching constructor for initialization of 'M'}}
109        m1(100) {  } // expected-error {{no matching constructor for initialization of 'M'}}
110  M m1;
111};
112
113struct P : M  {
114  P()  {  } // expected-error {{constructor for 'P' must explicitly initialize the base class 'M' which does not have a default constructor}} \
115            // expected-error {{member 'm'}}
116  M m; // expected-note {{member is declared here}}
117};
118
119struct Q {
120  Q() : f1(1,2),       // expected-error {{excess elements in scalar initializer}}
121        pf(0.0)  { }   // expected-error {{cannot initialize a member subobject of type 'float *' with an rvalue of type 'double'}}
122  float f1;
123
124  float *pf;
125};
126
127// A silly class used to demonstrate field-is-uninitialized in constructors with
128// multiple params.
129class TwoInOne { public: TwoInOne(TwoInOne a, TwoInOne b) {} };
130class InitializeUsingSelfTest {
131  bool A;
132  char* B;
133  int C;
134  TwoInOne D;
135  InitializeUsingSelfTest(int E)
136      : A(A),  // expected-warning {{field is uninitialized when used here}}
137        B((((B)))),  // expected-warning {{field is uninitialized when used here}}
138        C(A && InitializeUsingSelfTest::C),  // expected-warning {{field is uninitialized when used here}}
139        D(D,  // expected-warning {{field is uninitialized when used here}}
140          D) {}  // expected-warning {{field is uninitialized when used here}}
141};
142
143int IntWrapper(int i) { return 0; };
144class InitializeUsingSelfExceptions {
145  int A;
146  int B;
147  int C;
148  void *P;
149  InitializeUsingSelfExceptions(int B)
150      : 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.
151        B(B),  // Not a warning; B is a local variable.
152        C(sizeof(C)),  // sizeof doesn't reference contents, do not warn
153        P(&P) {} // address-of doesn't reference contents (the pointer may be dereferenced in the same expression but it would be rare; and weird)
154};
155
156class CopyConstructorTest {
157  bool A, B, C;
158  CopyConstructorTest(const CopyConstructorTest& rhs)
159      : A(rhs.A),
160        B(B),  // expected-warning {{field is uninitialized when used here}}
161        C(rhs.C || C) { }  // expected-warning {{field is uninitialized when used here}}
162};
163
164// Make sure we aren't marking default constructors when we shouldn't be.
165template<typename T>
166struct NDC {
167  T &ref;
168
169  NDC() { }
170  NDC(T &ref) : ref(ref) { }
171};
172
173struct X0 : NDC<int> {
174  X0(int &ref) : NDC<int>(ref), ndc(ref) { }
175
176  NDC<int> ndc;
177};
178
179namespace Test0 {
180
181struct A { A(); };
182
183struct B {
184  B() { }
185  const A a;
186};
187
188}
189
190namespace Test1 {
191  struct A {
192    enum Kind { Foo } Kind;
193    A() : Kind(Foo) {}
194  };
195}
196
197namespace Test2 {
198
199struct A {
200  A(const A&);
201};
202
203struct B : virtual A { };
204struct C : A, B { };
205
206C f(C c) {
207  return c;
208}
209
210}
211
212// Don't build implicit initializers for anonymous union fields when we already
213// have an explicit initializer for another field in the union.
214namespace PR7402 {
215  struct S {
216    union {
217      void* ptr_;
218      struct { int i_; };
219    };
220
221    template <typename T> S(T) : ptr_(0) { }
222  };
223
224  void f() {
225    S s(3);
226  }
227}
228
229// <rdar://problem/8308215>: don't crash.
230// Lots of questionable recovery here;  errors can change.
231namespace test3 {
232  class A : public std::exception {}; // expected-error {{undeclared identifier}} expected-error {{expected class name}} expected-note 3 {{candidate}} expected-note {{passing argument}}
233  class B : public A {
234  public:
235    B(const String& s, int e=0) // expected-error {{unknown type name}}
236      : A(e), m_String(s) , m_ErrorStr(__null) {} // expected-error {{no matching constructor}} expected-error {{does not name}}
237    B(const B& e)
238      : A(e), m_String(e.m_String), m_ErrorStr(__null) { // expected-error {{no viable conversion}} expected-error {{does not name}}
239    }
240  };
241}
242
243// PR8075
244namespace PR8075 {
245
246struct S1 {
247  enum { FOO = 42 };
248  static const int bar = 42;
249  static int baz();
250  S1(int);
251};
252
253const int S1::bar;
254
255struct S2 {
256  S1 s1;
257  S2() : s1(s1.FOO) {}
258};
259
260struct S3 {
261  S1 s1;
262  S3() : s1(s1.bar) {}
263};
264
265struct S4 {
266  S1 s1;
267  S4() : s1(s1.baz()) {}
268};
269
270}
271
272namespace PR12049 {
273  int function();
274
275  class Class
276  {
277  public:
278      Class() : member(function() {} // expected-note {{to match this '('}}
279
280      int member; // expected-error {{expected ')'}}
281  };
282}
283