2009-12-16 04:14:24 +08:00
|
|
|
// RUN: %clang_cc1 -fsyntax-only -Wall -verify %s
|
2009-08-29 13:16:22 +08:00
|
|
|
|
|
|
|
template<typename T> struct A {
|
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
|
|
|
A() : a(1) { } // expected-error{{cannot initialize a member subobject of type 'void *' with an rvalue of type 'int'}}
|
2009-08-29 13:16:22 +08:00
|
|
|
|
|
|
|
T a;
|
|
|
|
};
|
|
|
|
|
|
|
|
A<int> a0;
|
|
|
|
A<void*> a1; // expected-note{{in instantiation of member function 'A<void *>::A' requested here}}
|
|
|
|
|
|
|
|
template<typename T> struct B {
|
2010-04-10 15:37:23 +08:00
|
|
|
B() : b(1), // expected-warning {{field 'b' will be initialized after field 'a'}}
|
|
|
|
a(2) { }
|
2009-08-29 13:16:22 +08:00
|
|
|
|
|
|
|
int a;
|
|
|
|
int b;
|
|
|
|
};
|
|
|
|
|
2010-04-02 14:26:44 +08:00
|
|
|
B<int> b0; // expected-note {{in instantiation of member function 'B<int>::B' requested here}}
|
2009-08-30 06:22:07 +08:00
|
|
|
|
|
|
|
template <class T> struct AA { AA(int); };
|
|
|
|
template <class T> class BB : public AA<T> {
|
2010-04-10 03:03:51 +08:00
|
|
|
public:
|
2009-08-30 06:22:07 +08:00
|
|
|
BB() : AA<T>(1) {}
|
|
|
|
};
|
|
|
|
BB<int> x;
|
2012-12-19 10:27:38 +08:00
|
|
|
|
|
|
|
struct X {
|
|
|
|
X();
|
|
|
|
};
|
|
|
|
template<typename T>
|
|
|
|
struct Y {
|
|
|
|
Y() : x() {}
|
|
|
|
X x;
|
|
|
|
};
|
|
|
|
Y<int> y;
|
2012-12-21 16:13:35 +08:00
|
|
|
|
|
|
|
template<typename T> struct Array {
|
|
|
|
int a[3];
|
|
|
|
Array() : a() {}
|
|
|
|
};
|
|
|
|
Array<int> s;
|