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