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 {}; test()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}} test()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 {}; test()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 {}; test()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 {}; // expected-warning {{direct base 'Base' is inaccessible due to ambiguity:\n struct test4::Derived -> struct Base\n struct test4::Derived -> struct test4::A -> struct Base}} test()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 {}; test()61 void test() { 62 int (Derived::*d) = data_ptr; 63 int (Derived::*m)() = method_ptr; 64 } 65 } 66