1// RUN: %clang_cc1 -fsyntax-only -verify %s 2 3struct Base { 4 int data; 5 int method(); 6}; 7int (Base::*data_ptr) = &Base::data; 8int (Base::*method_ptr)() = &Base::method; 9 10namespace 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. 19namespace 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. 28namespace 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. 39namespace 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. 48namespace 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. 58namespace 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