Home | History | Annotate | Download | only in conv.mem
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s
      2 
      3 struct Base {
      4   int data;
      5   int method();
      6 };
      7 int (Base::*data_ptr) = &Base::data;
      8 int (Base::*method_ptr)() = &Base::method;
      9 
     10 namespace test0 {
     11   struct Derived : Base {};
     12   void test() {
     13     int (Derived::*d) = data_ptr;
     14     int (Derived::*m)() = method_ptr;
     15   }
     16 }
     17 
     18 // Can't be inaccessible.
     19 namespace test1 {
     20   struct Derived : private Base {}; // expected-note 2 {{declared private here}}
     21   void test() {
     22     int (Derived::*d) = data_ptr; // expected-error {{cannot cast private base class 'Base' to 'test1::Derived'}}
     23     int (Derived::*m)() = method_ptr; // expected-error {{cannot cast private base class 'Base' to 'test1::Derived'}}
     24   }
     25 };
     26 
     27 // Can't be ambiguous.
     28 namespace test2 {
     29   struct A : Base {};
     30   struct B : Base {};
     31   struct Derived : A, B {};
     32   void test() {
     33     int (Derived::*d) = data_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'Base' to pointer to member of derived class 'test2::Derived':}}
     34     int (Derived::*m)() = method_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'Base' to pointer to member of derived class 'test2::Derived':}}
     35   }
     36 }
     37 
     38 // Can't be virtual.
     39 namespace test3 {
     40   struct Derived : virtual Base {};
     41   void test() {
     42     int (Derived::*d) = data_ptr;  // expected-error {{conversion from pointer to member of class 'Base' to pointer to member of class 'test3::Derived' via virtual base 'Base' is not allowed}}
     43     int (Derived::*m)() = method_ptr; // expected-error {{conversion from pointer to member of class 'Base' to pointer to member of class 'test3::Derived' via virtual base 'Base' is not allowed}}
     44   }
     45 }
     46 
     47 // Can't be virtual even if there's a non-virtual path.
     48 namespace test4 {
     49   struct A : Base {};
     50   struct Derived : Base, virtual A {};
     51   void test() {
     52     int (Derived::*d) = data_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'Base' to pointer to member of derived class 'test4::Derived':}}
     53     int (Derived::*m)() = method_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'Base' to pointer to member of derived class 'test4::Derived':}}
     54   }
     55 }
     56 
     57 // PR6254: don't get thrown off by a virtual base.
     58 namespace test5 {
     59   struct A {};
     60   struct Derived : Base, virtual A {};
     61   void test() {
     62     int (Derived::*d) = data_ptr;
     63     int (Derived::*m)() = method_ptr;
     64   }
     65 }
     66