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