зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
392b3f5798
Коммит
a1366cbab8
|
@ -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();
|
||||
|
|
Загрузка…
Ссылка в новой задаче