llvm-project/clang/test/SemaCXX/constructor-initializer.cpp
Chandler Carruth 139e96216a Reapply r107235, this time with both my typo fixed, and a logical bug fixed.
Previously we relied on the presence of a member which needs no initialization
to prevent us from creating an additional initialization of the outer anonymous
union field. We have already correctly marked that field as initialized by the
member of the union (repeatedly due to the original bug this patch fixes) so we
simply need to bail out.

llvm-svn: 107242
2010-06-30 02:59:29 +00:00

224 lines
5.8 KiB
C++

// RUN: %clang_cc1 -Wreorder -fsyntax-only -verify %s
class A {
int m;
public:
A() : A::m(17) { } // expected-error {{member initializer 'm' does not name a non-static data member or base class}}
A(int);
};
class B : public A {
public:
B() : A(), m(1), n(3.14) { }
private:
int m;
float n;
};
class C : public virtual B {
public:
C() : B() { }
};
class D : public C {
public:
D() : B(), C() { }
};
class E : public D, public B {
public:
E() : B(), D() { } // expected-error{{base class initializer 'B' names both a direct base class and an inherited virtual base class}}
};
typedef int INT;
class F : public B {
public:
int B;
F() : B(17),
m(17), // expected-error{{member initializer 'm' does not name a non-static data member or base class}}
INT(17) // expected-error{{constructor initializer 'INT' (aka 'int') does not name a class}}
{
}
};
class G : A {
G() : A(10); // expected-error{{expected '{'}}
};
void f() : a(242) { } // expected-error{{only constructors take base initializers}}
class H : A {
H();
};
H::H() : A(10) { }
class X {};
class Y {};
struct S : Y, virtual X {
S ();
};
struct Z : S {
Z() : X(), S(), E() {} // expected-error {{type 'E' is not a direct or virtual base of 'Z'}}
};
class U {
union { int a; char* p; };
union { int b; double d; };
U() : a(1), // expected-note {{previous initialization is here}}
p(0), // expected-error {{initializing multiple members of anonymous union}}
d(1.0) {}
};
struct V {};
struct Base {};
struct Base1 {};
struct Derived : Base, Base1, virtual V {
Derived ();
};
struct Current : Derived {
int Derived;
Current() : Derived(1), ::Derived(), // expected-warning {{field 'Derived' will be initialized after base '::Derived'}} \
// expected-warning {{base class '::Derived' will be initialized after base 'Derived::V'}}
::Derived::Base(), // expected-error {{type '::Derived::Base' is not a direct or virtual base of 'Current'}}
Derived::Base1(), // expected-error {{type 'Derived::Base1' is not a direct or virtual base of 'Current'}}
Derived::V(),
::NonExisting(), // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
INT::NonExisting() {} // expected-error {{expected a class or namespace}} \
// expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
};
struct M { // expected-note 2 {{candidate constructor (the implicit copy constructor)}} \
// expected-note {{declared here}} \
// expected-note {{declared here}}
M(int i, int j); // expected-note 2 {{candidate constructor}}
};
struct N : M {
N() : M(1), // expected-error {{no matching constructor for initialization of 'M'}}
m1(100) { } // expected-error {{no matching constructor for initialization of 'M'}}
M m1;
};
struct P : M {
P() { } // expected-error {{constructor for 'P' must explicitly initialize the base class 'M' which does not have a default constructor}} \
// expected-error {{member 'm'}}
M m; // expected-note {{member is declared here}}
};
struct Q {
Q() : f1(1,2), // expected-error {{excess elements in scalar initializer}}
pf(0.0) { } // expected-error {{cannot initialize a member subobject of type 'float *' with an rvalue of type 'double'}}
float f1;
float *pf;
};
// A silly class used to demonstrate field-is-uninitialized in constructors with
// multiple params.
class TwoInOne { public: TwoInOne(TwoInOne a, TwoInOne b) {} };
class InitializeUsingSelfTest {
bool A;
char* B;
int C;
TwoInOne D;
InitializeUsingSelfTest(int E)
: A(A), // expected-warning {{field is uninitialized when used here}}
B((((B)))), // expected-warning {{field is uninitialized when used here}}
C(A && InitializeUsingSelfTest::C), // expected-warning {{field is uninitialized when used here}}
D(D, // expected-warning {{field is uninitialized when used here}}
D) {} // expected-warning {{field is uninitialized when used here}}
};
int IntWrapper(int i) { return 0; };
class InitializeUsingSelfExceptions {
int A;
int B;
InitializeUsingSelfExceptions(int B)
: 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.
B(B) {} // Not a warning; B is a local variable.
};
class CopyConstructorTest {
bool A, B, C;
CopyConstructorTest(const CopyConstructorTest& rhs)
: A(rhs.A),
B(B), // expected-warning {{field is uninitialized when used here}}
C(rhs.C || C) { } // expected-warning {{field is uninitialized when used here}}
};
// Make sure we aren't marking default constructors when we shouldn't be.
template<typename T>
struct NDC {
T &ref;
NDC() { }
NDC(T &ref) : ref(ref) { }
};
struct X0 : NDC<int> {
X0(int &ref) : NDC<int>(ref), ndc(ref) { }
NDC<int> ndc;
};
namespace Test0 {
struct A { A(); };
struct B {
B() { }
const A a;
};
}
namespace Test1 {
struct A {
enum Kind { Foo } Kind;
A() : Kind(Foo) {}
};
}
namespace Test2 {
struct A {
A(const A&);
};
struct B : virtual A { };
struct C : A, B { };
C f(C c) {
return c;
}
}
// Don't build implicit initializers for anonymous union fields when we already
// have an explicit initializer for another field in the union.
namespace PR7402 {
struct S {
union {
void* ptr_;
struct { int i_; };
};
template <typename T> S(T) : ptr_(0) { }
};
void f() {
S s(3);
}
}