2009-12-16 04:14:24 +08:00
// RUN: %clang_cc1 -Wreorder -fsyntax-only -verify %s
2008-11-05 12:29:56 +08:00
class A {
int m ;
2010-04-10 03:03:51 +08:00
public :
2009-07-01 07:26:25 +08:00
A ( ) : A : : m ( 17 ) { } // expected-error {{member initializer 'm' does not name a non-static data member or base class}}
2009-07-23 08:42:24 +08:00
A ( int ) ;
2008-11-05 12:29:56 +08:00
} ;
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 ( ) { }
} ;
2015-01-19 09:44:02 +08:00
class E : public D , public B { // expected-warning{{direct base 'B' is inaccessible due to ambiguity:\n class E -> class D -> class C -> class B\n class E -> class B}}
2008-11-05 12:29:56 +08:00
public :
2010-03-10 19:27:22 +08:00
E ( ) : B ( ) , D ( ) { } // expected-error{{base class initializer 'B' names both a direct base class and an inherited virtual base class}}
2008-11-05 12:29:56 +08:00
} ;
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}}
2009-02-20 07:45:49 +08:00
INT ( 17 ) // expected-error{{constructor initializer 'INT' (aka 'int') does not name a class}}
2008-11-05 12:29:56 +08:00
{
}
} ;
2008-11-11 00:59:40 +08:00
class G : A {
G ( ) : A ( 10 ) ; // expected-error{{expected '{'}}
} ;
2009-03-25 10:58:17 +08:00
void f ( ) : a ( 242 ) { } // expected-error{{only constructors take base initializers}}
class H : A {
H ( ) ;
} ;
H : : H ( ) : A ( 10 ) { }
2009-07-01 01:34:52 +08:00
class X { } ;
class Y { } ;
struct S : Y , virtual X {
S ( ) ;
} ;
struct Z : S {
2010-03-10 19:27:22 +08:00
Z ( ) : X ( ) , S ( ) , E ( ) { } // expected-error {{type 'E' is not a direct or virtual base of 'Z'}}
2009-07-01 01:34:52 +08:00
} ;
2009-07-01 05:52:59 +08:00
class U {
union { int a ; char * p ; } ;
union { int b ; double d ; } ;
2010-04-10 17:28:51 +08:00
U ( ) : a ( 1 ) , // expected-note {{previous initialization is here}}
2011-11-17 14:01:57 +08:00
p ( 0 ) , // expected-error {{initializing multiple members of union}}
2010-04-10 17:28:51 +08:00
d ( 1.0 ) { }
2009-07-01 05:52:59 +08:00
} ;
2009-07-01 07:26:25 +08:00
struct V { } ;
struct Base { } ;
struct Base1 { } ;
struct Derived : Base , Base1 , virtual V {
Derived ( ) ;
} ;
struct Current : Derived {
int Derived ;
2010-04-10 15:37:23 +08:00
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'}}
2009-07-01 07:26:25 +08:00
: : 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'}}
2010-04-10 15:37:23 +08:00
Derived : : V ( ) ,
2009-07-01 07:26:25 +08:00
: : NonExisting ( ) , // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
2015-01-19 03:05:48 +08:00
INT : : NonExisting ( ) { } / / expected - error { { ' INT ' ( aka ' int ' ) is not a class , namespace , or enumeration } } \
2009-09-09 23:08:12 +08:00
// expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
2009-07-01 07:26:25 +08:00
} ;
2009-07-24 07:32:59 +08:00
2010-01-13 08:25:19 +08:00
struct M { / / expected - note 2 { { candidate constructor ( the implicit copy constructor ) } } \
2009-11-09 09:05:47 +08:00
/ / expected - note { { declared here } } \
// expected-note {{declared here}}
2010-01-06 17:43:14 +08:00
M ( int i , int j ) ; // expected-note 2 {{candidate constructor}}
2009-07-24 07:32:59 +08:00
} ;
struct N : M {
2010-03-10 19:27:22 +08:00
N ( ) : M ( 1 ) , // expected-error {{no matching constructor for initialization of 'M'}}
m1 ( 100 ) { } // expected-error {{no matching constructor for initialization of 'M'}}
2009-07-24 07:32:59 +08:00
M m1 ;
} ;
2009-11-09 09:05:47 +08:00
struct P : M {
2010-03-10 19:27:22 +08:00
P ( ) { } / / expected - error { { constructor for ' P ' must explicitly initialize the base class ' M ' which does not have a default constructor } } \
2009-11-09 09:05:47 +08:00
// expected-error {{member 'm'}}
M m ; // expected-note {{member is declared here}}
2009-07-24 07:32:59 +08:00
} ;
2009-07-25 04:28:49 +08:00
struct Q {
Rework base and member initialization in constructors, with several
(necessarily simultaneous) changes:
- CXXBaseOrMemberInitializer now contains only a single initializer
rather than a set of initialiation arguments + a constructor. The
single initializer covers all aspects of initialization, including
constructor calls as necessary but also cleanup of temporaries
created by the initializer (which we never handled
before!).
- Rework + simplify code generation for CXXBaseOrMemberInitializers,
since we can now just emit the initializer as an initializer.
- Switched base and member initialization over to the new
initialization code (InitializationSequence), so that it
- Improved diagnostics for the new initialization code when
initializing bases and members, to match the diagnostics produced
by the previous (special-purpose) code.
- Simplify the representation of type-checked constructor initializers in
templates; instead of keeping the fully-type-checked AST, which is
rather hard to undo at template instantiation time, throw away the
type-checked AST and store the raw expressions in the AST. This
simplifies instantiation, but loses a little but of information in
the AST.
- When type-checking implicit base or member initializers within a
dependent context, don't add the generated initializers into the
AST, because they'll look like they were explicit.
- Record in CXXConstructExpr when the constructor call is to
initialize a base class, so that CodeGen does not have to infer it
from context. This ensures that we call the right kind of
constructor.
There are also a few "opportunity" fixes here that were needed to not
regress, for example:
- Diagnose default-initialization of a const-qualified class that
does not have a user-declared default constructor. We had this
diagnostic specifically for bases and members, but missed it for
variables. That's fixed now.
- When defining the implicit constructors, destructor, and
copy-assignment operator, set the CurContext to that constructor
when we're defining the body.
llvm-svn: 94952
2010-01-31 17:12:51 +08:00
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'}}
2009-07-25 04:28:49 +08:00
float f1 ;
float * pf ;
} ;
2009-11-05 07:02:40 +08:00
// A silly class used to demonstrate field-is-uninitialized in constructors with
// multiple params.
2012-06-15 07:11:34 +08:00
int IntParam ( int i ) { return 0 ; } ;
2010-04-10 03:03:51 +08:00
class TwoInOne { public : TwoInOne ( TwoInOne a , TwoInOne b ) { } } ;
2009-11-05 07:02:40 +08:00
class InitializeUsingSelfTest {
bool A ;
char * B ;
int C ;
TwoInOne D ;
2012-06-15 07:11:34 +08:00
int E ;
InitializeUsingSelfTest ( int F )
2012-09-21 16:58:33 +08:00
: A ( A ) , // expected-warning {{field 'A' is uninitialized when used here}}
B ( ( ( ( B ) ) ) ) , // expected-warning {{field 'B' is uninitialized when used here}}
C ( A & & InitializeUsingSelfTest : : C ) , // expected-warning {{field 'C' is uninitialized when used here}}
D ( D , // expected-warning {{field 'D' is uninitialized when used here}}
D ) , // expected-warning {{field 'D' is uninitialized when used here}}
E ( IntParam ( E ) ) { } // expected-warning {{field 'E' is uninitialized when used here}}
2009-11-05 07:02:40 +08:00
} ;
2012-06-15 07:11:34 +08:00
int IntWrapper ( int & i ) { return 0 ; } ;
2009-11-05 07:02:40 +08:00
class InitializeUsingSelfExceptions {
int A ;
int B ;
2010-09-21 18:47:20 +08:00
int C ;
void * P ;
2009-11-05 07:02:40 +08:00
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.
2010-09-21 18:47:20 +08:00
B ( B ) , // Not a warning; B is a local variable.
C ( sizeof ( C ) ) , // sizeof doesn't reference contents, do not warn
P ( & P ) { } // address-of doesn't reference contents (the pointer may be dereferenced in the same expression but it would be rare; and weird)
2009-11-05 07:02:40 +08:00
} ;
class CopyConstructorTest {
bool A , B , C ;
CopyConstructorTest ( const CopyConstructorTest & rhs )
: A ( rhs . A ) ,
2012-09-21 16:58:33 +08:00
B ( B ) , // expected-warning {{field 'B' is uninitialized when used here}}
C ( rhs . C | | C ) { } // expected-warning {{field 'C' is uninitialized when used here}}
2009-11-05 07:02:40 +08:00
} ;
2009-11-15 16:51:10 +08:00
// 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 ;
} ;
2010-04-23 11:07:47 +08:00
namespace Test0 {
struct A { A ( ) ; } ;
struct B {
B ( ) { }
const A a ;
} ;
}
2010-04-24 02:46:30 +08:00
2010-04-25 09:00:05 +08:00
namespace Test1 {
2010-04-24 02:46:30 +08:00
struct A {
enum Kind { Foo } Kind ;
A ( ) : Kind ( Foo ) { }
} ;
}
2010-04-25 09:00:05 +08:00
namespace Test2 {
struct A {
A ( const A & ) ;
} ;
struct B : virtual A { } ;
2015-01-19 09:44:02 +08:00
struct C : A , B { } ; // expected-warning{{direct base 'Test2::A' is inaccessible due to ambiguity:\n struct Test2::C -> struct Test2::A\n struct Test2::C -> struct Test2::B -> struct Test2::A}}
2010-04-25 09:00:05 +08:00
C f ( C c ) {
return c ;
}
}
2010-06-30 10:59:29 +08:00
// 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 ) ;
}
}
2010-08-17 15:23:57 +08:00
// <rdar://problem/8308215>: don't crash.
// Lots of questionable recovery here; errors can change.
namespace test3 {
2013-12-21 08:49:51 +08:00
class A : public std : : exception { } ; // expected-error {{undeclared identifier}} expected-error {{expected class name}} expected-note 2 {{candidate}}
2010-08-17 15:23:57 +08:00
class B : public A {
public :
B ( const String & s , int e = 0 ) // expected-error {{unknown type name}}
: A ( e ) , m_String ( s ) , m_ErrorStr ( __null ) { } // expected-error {{no matching constructor}} expected-error {{does not name}}
B ( const B & e )
2013-03-27 07:36:30 +08:00
: A ( e ) , m_String ( e . m_String ) , m_ErrorStr ( __null ) { / / expected - error { { does not name } } \
2013-12-21 08:49:51 +08:00
// expected-error {{no member named 'm_String' in 'test3::B'}}
2010-08-17 15:23:57 +08:00
}
} ;
}
2010-10-06 10:43:25 +08:00
// PR8075
namespace PR8075 {
struct S1 {
enum { FOO = 42 } ;
static const int bar = 42 ;
static int baz ( ) ;
S1 ( int ) ;
} ;
const int S1 : : bar ;
struct S2 {
S1 s1 ;
S2 ( ) : s1 ( s1 . FOO ) { }
} ;
struct S3 {
S1 s1 ;
S3 ( ) : s1 ( s1 . bar ) { }
} ;
struct S4 {
S1 s1 ;
S4 ( ) : s1 ( s1 . baz ( ) ) { }
} ;
}
2012-02-22 12:49:04 +08:00
namespace PR12049 {
int function ( ) ;
class Class
{
public :
Class ( ) : member ( function ( ) { } // expected-note {{to match this '('}}
int member ; // expected-error {{expected ')'}}
} ;
}
2012-11-15 16:19:20 +08:00
namespace PR14073 {
struct S1 { union { int n ; } ; S1 ( ) : n ( n ) { } } ; // expected-warning {{field 'n' is uninitialized when used here}}
struct S2 { union { union { int n ; } ; char c ; } ; S2 ( ) : n ( n ) { } } ; // expected-warning {{field 'n' is uninitialized when used here}}
struct S3 { struct { int n ; } ; S3 ( ) : n ( n ) { } } ; // expected-warning {{field 'n' is uninitialized when used here}}
}