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">;
def err_using_decl_constructor : Error<
"using declaration can not refer to a constructor">;
def warn_cxx98_compat_using_decl_constructor : Warning<
"inherited constructors are incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
def err_using_decl_constructor_unsupported : Error<
"inheriting constructors are not supported">;
// 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<
"using declaration can not refer to a destructor">;
def err_using_decl_template_id : Error<

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

@ -5925,10 +5925,12 @@ Decl *Sema::ActOnUsingDeclaration(Scope *S,
case UnqualifiedId::IK_ConstructorName:
case UnqualifiedId::IK_ConstructorTemplateId:
// C++0x inherited constructors.
// C++11 inheriting constructors.
Diag(Name.getLocStart(),
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)
<< SS.getRange();

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

@ -9,15 +9,15 @@ struct B1 {
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:
// A using-declaration is a declaration and can therefore be used repeatedly
// where (and only where) multiple declarations are allowed.
struct I1 : B1 {
using B1::B1; // expected-note {{previous using declaration}}
using B1::B1; // expected-error {{redeclaration of using decl}}
using B1::B1; // expected-note {{previous using declaration}} expected-error {{not supported}}
using B1::B1; // expected-error {{redeclaration of using decl}} expected-error {{not supported}}
};
// C++0x [namespace.udecl]p3:
@ -27,31 +27,31 @@ struct I1 : B1 {
// shall name a direct base class of the class being defined.
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 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<char> bc;
B<double> bd; // expected-note {{here}}
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<char> cc; // expected-note {{here}}
template<typename T> struct D : A<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}}
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}}

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

@ -5,7 +5,7 @@ struct B1 {
B1(int, int);
};
struct D1 : B1 {
using B1::B1;
using B1::B1; // expected-error {{not supported}}
};
D1 d1a(1), d1b(1, 1);
@ -15,7 +15,7 @@ struct B2 {
explicit B2(int, int = 0, int = 0);
};
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);
@ -25,18 +25,18 @@ struct B3 {
B3(void*); // expected-note {{inherited from here}}
};
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}}
template<typename T> struct T1 : B1 {
using B1::B1;
using B1::B1; // expected-error {{not supported}}
};
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> {
using T1<T>::T1;
using T1<T>::T1; // expected-error {{not supported}}
};
struct U {
friend T1<int>::T1(int);

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

@ -8,12 +8,12 @@ struct B2 {
B2(int); // expected-note {{conflicting constructor}}
};
struct D1 : B1, B2 {
using B1::B1; // expected-note {{inherited here}}
using B2::B2; // expected-error {{already inherited constructor with the same signature}}
using B1::B1; // expected-note {{inherited here}} expected-error {{not supported}}
using B2::B2; // expected-error {{already inherited constructor with the same signature}} expected-error {{not supported}}
};
struct D2 : B1, B2 {
using B1::B1;
using B2::B2;
using B1::B1; // expected-error {{not supported}}
using B2::B2; // expected-error {{not supported}}
D2(int);
};
@ -22,8 +22,8 @@ template<typename T> struct B3 {
};
template<typename T> struct B4 : B3<T>, B1 {
B4();
using B3<T>::B3; // expected-note {{inherited here}}
using B1::B1; // expected-error {{already inherited}}
using B3<T>::B3; // expected-note {{inherited here}} expected-error {{not supported}}
using B1::B1; // expected-error {{already inherited}} expected-error {{not supported}}
};
B4<char> b4c;
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
// XFAIL: *
// PR12219
struct A { A(int); virtual ~A(); };
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}}
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 {
InhCtorBase(int);
};
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 {
static void MemberFn();