constructor-initializer.cpp revision b1622a1fd7b7f4ab8d00d0183d17c90ad25c14e3
1// RUN: %clang_cc1 -Wreorder -fsyntax-only -verify %s
2class 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
8class B : public A {
9public:
10  B() : A(), m(1), n(3.14) { }
11
12private:
13  int m;
14  float n;
15};
16
17
18class C : public virtual B {
19public:
20  C() : B() { }
21};
22
23class D : public C {
24public:
25  D() : B(), C() { }
26};
27
28class E : public D, public B {
29public:
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
34typedef int INT;
35
36class F : public B {
37public:
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
47class G : A {
48  G() : A(10); // expected-error{{expected '{'}}
49};
50
51void f() : a(242) { } // expected-error{{only constructors take base initializers}}
52
53class H : A {
54  H();
55};
56
57H::H() : A(10) { }
58
59
60class  X {};
61class Y {};
62
63struct S : Y, virtual X {
64  S ();
65};
66
67struct Z : S {
68  Z() : X(), S(), E()  {} // expected-error {{type 'class E' is not a direct or virtual base of 'Z'}}
69};
70
71class 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
79struct V {};
80struct Base {};
81struct Base1 {};
82
83struct Derived : Base, Base1, virtual V {
84  Derived ();
85};
86
87struct 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
100struct M {              // expected-note 2 {{candidate is 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
106struct N : M  {
107  N() : M(1),        // expected-error {{no matching constructor for initialization of 'M'}}
108        m1(100) {  } // expected-error {{no matching constructor for initialization of 'm1'}}
109  M m1;
110};
111
112struct 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
118struct Q {
119  Q() : f1(1,2),       // expected-error {{Too many arguments for member initializer 'f1'}}
120        pf(0.0)  { }   // expected-error {{incompatible type passing 'double', expected 'float *'}}
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.
128class TwoInOne { TwoInOne(TwoInOne a, TwoInOne b) {} };
129class 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
142int IntWrapper(int i) { return 0; };
143class 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
151class 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.
160template<typename T>
161struct NDC {
162  T &ref;
163
164  NDC() { }
165  NDC(T &ref) : ref(ref) { }
166};
167
168struct X0 : NDC<int> {
169  X0(int &ref) : NDC<int>(ref), ndc(ref) { }
170
171  NDC<int> ndc;
172};
173