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 {}; // 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}} |
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 | |