PR12224 (sort of): Diagnose inheriting constructor declarations in C++11 mode.

We do not support IRGen for these, and get some parts of the semantic analysis
wrong.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@155728 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Richard Smith 2012-04-27 19:33:05 +00:00
Родитель 392b3f5798
Коммит a1366cbab8
7 изменённых файлов: 38 добавлений и 26 удалений

Просмотреть файл

@ -231,9 +231,13 @@ def err_using_decl_can_not_refer_to_namespace : Error<
"using declaration can not refer to namespace">; "using declaration can not refer to namespace">;
def err_using_decl_constructor : Error< def err_using_decl_constructor : Error<
"using declaration can not refer to a constructor">; "using declaration can not refer to a constructor">;
def warn_cxx98_compat_using_decl_constructor : Warning< def err_using_decl_constructor_unsupported : Error<
"inherited constructors are incompatible with C++98">, "inheriting constructors are not supported">;
InGroup<CXX98Compat>, DefaultIgnore; // FIXME: Replace the above error with this warning if support for
// inheriting constructors is implemented.
//def warn_cxx98_compat_using_decl_constructor : Warning<
// "inheriting constructors are incompatible with C++98">,
// InGroup<CXX98Compat>, DefaultIgnore;
def err_using_decl_destructor : Error< def err_using_decl_destructor : Error<
"using declaration can not refer to a destructor">; "using declaration can not refer to a destructor">;
def err_using_decl_template_id : Error< def err_using_decl_template_id : Error<

Просмотреть файл

@ -5925,10 +5925,12 @@ Decl *Sema::ActOnUsingDeclaration(Scope *S,
case UnqualifiedId::IK_ConstructorName: case UnqualifiedId::IK_ConstructorName:
case UnqualifiedId::IK_ConstructorTemplateId: case UnqualifiedId::IK_ConstructorTemplateId:
// C++0x inherited constructors. // C++11 inheriting constructors.
Diag(Name.getLocStart(), Diag(Name.getLocStart(),
getLangOpts().CPlusPlus0x ? getLangOpts().CPlusPlus0x ?
diag::warn_cxx98_compat_using_decl_constructor : // FIXME: Produce warn_cxx98_compat_using_decl_constructor
// instead once inheriting constructors work.
diag::err_using_decl_constructor_unsupported :
diag::err_using_decl_constructor) diag::err_using_decl_constructor)
<< SS.getRange(); << SS.getRange();

Просмотреть файл

@ -9,15 +9,15 @@ struct B1 {
B1(int); B1(int);
}; };
using B1::B1; // expected-error {{using declaration can not refer to class member}} using B1::B1; // expected-error {{using declaration can not refer to class member}} expected-error {{not supported}}
// C++0x [namespace.udecl]p10: // C++0x [namespace.udecl]p10:
// A using-declaration is a declaration and can therefore be used repeatedly // A using-declaration is a declaration and can therefore be used repeatedly
// where (and only where) multiple declarations are allowed. // where (and only where) multiple declarations are allowed.
struct I1 : B1 { struct I1 : B1 {
using B1::B1; // expected-note {{previous using declaration}} using B1::B1; // expected-note {{previous using declaration}} expected-error {{not supported}}
using B1::B1; // expected-error {{redeclaration of using decl}} using B1::B1; // expected-error {{redeclaration of using decl}} expected-error {{not supported}}
}; };
// C++0x [namespace.udecl]p3: // C++0x [namespace.udecl]p3:
@ -27,31 +27,31 @@ struct I1 : B1 {
// shall name a direct base class of the class being defined. // shall name a direct base class of the class being defined.
struct D1 : I1 { struct D1 : I1 {
using B1::B1; // expected-error {{'B1' is not a direct base of 'D1', can not inherit constructors}} using B1::B1; // expected-error {{'B1' is not a direct base of 'D1', can not inherit constructors}} expected-error {{not supported}}
}; };
template<typename T> struct A {}; template<typename T> struct A {};
template<typename T> struct B : A<bool>, A<char> { template<typename T> struct B : A<bool>, A<char> {
using A<T>::A; // expected-error {{'A<double>::', which is not a base class of 'B<double>'}} using A<T>::A; // expected-error {{'A<double>::', which is not a base class of 'B<double>'}} expected-error {{not supported}}
}; };
B<bool> bb; B<bool> bb;
B<char> bc; B<char> bc;
B<double> bd; // expected-note {{here}} B<double> bd; // expected-note {{here}}
template<typename T> struct C : A<T> { template<typename T> struct C : A<T> {
using A<bool>::A; // expected-error {{'A<bool>::', which is not a base class of 'C<char>'}} using A<bool>::A; // expected-error {{'A<bool>::', which is not a base class of 'C<char>'}} expected-error {{not supported}}
}; };
C<bool> cb; C<bool> cb;
C<char> cc; // expected-note {{here}} C<char> cc; // expected-note {{here}}
template<typename T> struct D : A<T> {}; template<typename T> struct D : A<T> {};
template<typename T> struct E : D<T> { template<typename T> struct E : D<T> {
using A<bool>::A; // expected-error {{'A<bool>' is not a direct base of 'E<bool>', can not inherit}} using A<bool>::A; // expected-error {{'A<bool>' is not a direct base of 'E<bool>', can not inherit}} expected-error {{not supported}}
}; };
E<bool> eb; // expected-note {{here}} E<bool> eb; // expected-note {{here}}
template<typename T> struct F : D<bool> { template<typename T> struct F : D<bool> {
using A<T>::A; // expected-error {{'A<bool>' is not a direct base of 'F<bool>'}} using A<T>::A; // expected-error {{'A<bool>' is not a direct base of 'F<bool>'}} expected-error {{not supported}}
}; };
F<bool> fb; // expected-note {{here}} F<bool> fb; // expected-note {{here}}

Просмотреть файл

@ -5,7 +5,7 @@ struct B1 {
B1(int, int); B1(int, int);
}; };
struct D1 : B1 { struct D1 : B1 {
using B1::B1; using B1::B1; // expected-error {{not supported}}
}; };
D1 d1a(1), d1b(1, 1); D1 d1a(1), d1b(1, 1);
@ -15,7 +15,7 @@ struct B2 {
explicit B2(int, int = 0, int = 0); explicit B2(int, int = 0, int = 0);
}; };
struct D2 : B2 { // expected-note 2 {{candidate constructor}} struct D2 : B2 { // expected-note 2 {{candidate constructor}}
using B2::B2; using B2::B2; // expected-error {{not supported}}
}; };
D2 d2a(1), d2b(1, 1), d2c(1, 1, 1); D2 d2a(1), d2b(1, 1), d2c(1, 1, 1);
@ -25,18 +25,18 @@ struct B3 {
B3(void*); // expected-note {{inherited from here}} B3(void*); // expected-note {{inherited from here}}
}; };
struct D3 : B3 { // expected-note 2 {{candidate constructor}} struct D3 : B3 { // expected-note 2 {{candidate constructor}}
using B3::B3; // expected-note {{candidate constructor (inherited)}} using B3::B3; // expected-note {{candidate constructor (inherited)}} expected-error {{not supported}}
}; };
D3 fd3() { return 1; } // expected-error {{no viable conversion}} D3 fd3() { return 1; } // expected-error {{no viable conversion}}
template<typename T> struct T1 : B1 { template<typename T> struct T1 : B1 {
using B1::B1; using B1::B1; // expected-error {{not supported}}
}; };
template<typename T> struct T2 : T1<T> { template<typename T> struct T2 : T1<T> {
using T1<int>::T1; using T1<int>::T1; // expected-error {{not supported}}
}; };
template<typename T> struct T3 : T1<int> { template<typename T> struct T3 : T1<int> {
using T1<T>::T1; using T1<T>::T1; // expected-error {{not supported}}
}; };
struct U { struct U {
friend T1<int>::T1(int); friend T1<int>::T1(int);

Просмотреть файл

@ -8,12 +8,12 @@ struct B2 {
B2(int); // expected-note {{conflicting constructor}} B2(int); // expected-note {{conflicting constructor}}
}; };
struct D1 : B1, B2 { struct D1 : B1, B2 {
using B1::B1; // expected-note {{inherited here}} using B1::B1; // expected-note {{inherited here}} expected-error {{not supported}}
using B2::B2; // expected-error {{already inherited constructor with the same signature}} using B2::B2; // expected-error {{already inherited constructor with the same signature}} expected-error {{not supported}}
}; };
struct D2 : B1, B2 { struct D2 : B1, B2 {
using B1::B1; using B1::B1; // expected-error {{not supported}}
using B2::B2; using B2::B2; // expected-error {{not supported}}
D2(int); D2(int);
}; };
@ -22,8 +22,8 @@ template<typename T> struct B3 {
}; };
template<typename T> struct B4 : B3<T>, B1 { template<typename T> struct B4 : B3<T>, B1 {
B4(); B4();
using B3<T>::B3; // expected-note {{inherited here}} using B3<T>::B3; // expected-note {{inherited here}} expected-error {{not supported}}
using B1::B1; // expected-error {{already inherited}} using B1::B1; // expected-error {{already inherited}} expected-error {{not supported}}
}; };
B4<char> b4c; B4<char> b4c;
B4<int> b4i; // expected-note {{here}} B4<int> b4i; // expected-note {{here}}

Просмотреть файл

@ -1,5 +1,7 @@
// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
// XFAIL: *
// PR12219 // PR12219
struct A { A(int); virtual ~A(); }; struct A { A(int); virtual ~A(); };
struct B : A { using A::A; ~B(); }; struct B : A { using A::A; ~B(); };

Просмотреть файл

@ -138,12 +138,16 @@ bool no_except_expr = noexcept(1 + 1); // expected-warning {{noexcept expression
void *null = nullptr; // expected-warning {{'nullptr' is incompatible with C++98}} void *null = nullptr; // expected-warning {{'nullptr' is incompatible with C++98}}
static_assert(true, "!"); // expected-warning {{static_assert declarations are incompatible with C++98}} static_assert(true, "!"); // expected-warning {{static_assert declarations are incompatible with C++98}}
// FIXME: Reintroduce this test if support for inheriting constructors is
// implemented.
#if 0
struct InhCtorBase { struct InhCtorBase {
InhCtorBase(int); InhCtorBase(int);
}; };
struct InhCtorDerived : InhCtorBase { struct InhCtorDerived : InhCtorBase {
using InhCtorBase::InhCtorBase; // expected-warning {{inherited constructors are incompatible with C++98}} using InhCtorBase::InhCtorBase; // xpected-warning {{inheriting constructors are incompatible with C++98}}
}; };
#endif
struct FriendMember { struct FriendMember {
static void MemberFn(); static void MemberFn();