Commit 2fe44613 authored by Bill Wendling's avatar Bill Wendling
Browse files

Merging r155728:

------------------------------------------------------------------------
r155728 | rsmith | 2012-04-27 12:33:05 -0700 (Fri, 27 Apr 2012) | 4 lines

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.

------------------------------------------------------------------------

llvm-svn: 155731
parent 5f15b4e8
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -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<
+4 −2
Original line number Diff line number Diff line
@@ -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();

+8 −8
Original line number Diff line number Diff line
@@ -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}}
+6 −6
Original line number Diff line number Diff line
@@ -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);
+6 −6
Original line number Diff line number Diff line
@@ -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}}
Loading