xref: /llvm-project/clang/test/SemaCXX/constructor-initializer.cpp (revision 598caeee376ad4ff58d4e77e03782b9d084df748)
1 // RUN: clang-cc -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                         // FIXME. This is bad message!
101 struct M {              // expected-note {{candidate function}} \
102                         // expected-note {{candidate function}} \
103                         // expected-note {{declared here}} \
104                         // expected-note {{declared here}}
105   M(int i, int j);      // expected-note {{candidate function}} \
106                         // // expected-note {{candidate function}}
107 };
108 
109 struct N : M  {
110   N() : M(1),        // expected-error {{no matching constructor for initialization of 'M'}}
111         m1(100) {  } // expected-error {{no matching constructor for initialization of 'm1'}}
112   M m1;
113 };
114 
115 struct P : M  {
116   P()  {  } // expected-error {{base class 'struct M'}} \
117             // expected-error {{member 'm'}}
118   M m; // expected-note {{member is declared here}}
119 };
120 
121 struct Q {
122   Q() : f1(1,2),       // expected-error {{Too many arguments for member initializer 'f1'}}
123         pf(0.0)  { }   // expected-error {{incompatible type passing 'double', expected 'float *'}}
124   float f1;
125 
126   float *pf;
127 };
128 
129 // A silly class used to demonstrate field-is-uninitialized in constructors with
130 // multiple params.
131 class TwoInOne { TwoInOne(TwoInOne a, TwoInOne b) {} };
132 class InitializeUsingSelfTest {
133   bool A;
134   char* B;
135   int C;
136   TwoInOne D;
137   InitializeUsingSelfTest(int E)
138       : A(A),  // expected-warning {{field is uninitialized when used here}}
139         B((((B)))),  // expected-warning {{field is uninitialized when used here}}
140         C(A && InitializeUsingSelfTest::C),  // expected-warning {{field is uninitialized when used here}}
141         D(D,  // expected-warning {{field is uninitialized when used here}}
142           D) {}  // expected-warning {{field is uninitialized when used here}}
143 };
144 
145 int IntWrapper(int i) { return 0; };
146 class InitializeUsingSelfExceptions {
147   int A;
148   int B;
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 };
153 
154 class CopyConstructorTest {
155   bool A, B, C;
156   CopyConstructorTest(const CopyConstructorTest& rhs)
157       : A(rhs.A),
158         B(B),  // expected-warning {{field is uninitialized when used here}}
159         C(rhs.C || C) { }  // expected-warning {{field is uninitialized when used here}}
160 };
161 
162 // Make sure we aren't marking default constructors when we shouldn't be.
163 template<typename T>
164 struct NDC {
165   T &ref;
166 
167   NDC() { }
168   NDC(T &ref) : ref(ref) { }
169 };
170 
171 struct X0 : NDC<int> {
172   X0(int &ref) : NDC<int>(ref), ndc(ref) { }
173 
174   NDC<int> ndc;
175 };
176