зеркало из 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">;
|
"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();
|
||||||
|
|
Загрузка…
Ссылка в новой задаче