p4.cpp revision 6b2accb4793e16b2e93a8c2589f5df702231f17a
1// RUN: %clang_cc1 -fsyntax-only -faccess-control -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 'struct Base' to 'struct test1::Derived'}}
23    int (Derived::*m)() = method_ptr; // expected-error {{cannot cast private base class 'struct Base' to 'struct 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 'struct Base' to pointer to member of derived class 'struct test2::Derived'}}
34    int (Derived::*m)() = method_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'struct Base' to pointer to member of derived class 'struct 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 'struct Base' to pointer to member of class 'struct test3::Derived' via virtual base 'struct Base' is not allowed}}
43    int (Derived::*m)() = method_ptr; // expected-error {{conversion from pointer to member of class 'struct Base' to pointer to member of class 'struct test3::Derived' via virtual base 'struct 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 'struct Base' to pointer to member of derived class 'struct test4::Derived'}}
53    int (Derived::*m)() = method_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'struct Base' to pointer to member of derived class 'struct 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