1 // RUN: clang-cc -fsyntax-only -verify %s 2 3 struct A {}; 4 enum B { Dummy }; 5 namespace C {} 6 struct D : A {}; 7 struct E : A {}; 8 struct F : D, E {}; 9 struct G : virtual D {}; 10 11 int A::*pdi1; 12 int (::A::*pdi2); 13 int (A::*pfi)(int); 14 15 int B::*pbi; // expected-error {{expected a class or namespace}} \ 16 // expected-error{{does not point into a class}} 17 int C::*pci; // expected-error {{'pci' does not point into a class}} 18 void A::*pdv; // expected-error {{'pdv' declared as a member pointer to void}} 19 int& A::*pdr; // expected-error {{'pdr' declared as a member pointer to a reference}} 20 21 void f() { 22 // This requires tentative parsing. 23 int (A::*pf)(int, int); 24 25 // Implicit conversion to bool. 26 bool b = pdi1; 27 b = pfi; 28 29 // Conversion from null pointer constant. 30 pf = 0; 31 pf = __null; 32 33 // Conversion to member of derived. 34 int D::*pdid = pdi1; 35 pdid = pdi2; 36 37 // Fail conversion due to ambiguity and virtuality. 38 int F::*pdif = pdi1; // expected-error {{ambiguous conversion from pointer to member of base class 'struct A' to pointer to member of derived class 'struct F'}} expected-error {{incompatible type}} 39 int G::*pdig = pdi1; // expected-error {{conversion from pointer to member of class 'struct A' to pointer to member of class 'struct G' via virtual base 'struct D' is not allowed}} expected-error {{incompatible type}} 40 41 // Conversion to member of base. 42 pdi1 = pdid; // expected-error {{incompatible type assigning 'int struct D::*', expected 'int struct A::*'}} 43 } 44 45 struct TheBase 46 { 47 void d(); 48 }; 49 50 struct HasMembers : TheBase 51 { 52 int i; 53 void f(); 54 55 void g(); 56 void g(int); 57 static void g(double); 58 }; 59 60 namespace Fake 61 { 62 int i; 63 void f(); 64 } 65 66 void g() { 67 HasMembers hm; 68 69 int HasMembers::*pmi = &HasMembers::i; 70 int *pni = &Fake::i; 71 int *pmii = &hm.i; 72 73 void (HasMembers::*pmf)() = &HasMembers::f; 74 void (*pnf)() = &Fake::f; 75 &hm.f; // FIXME: needs diagnostic expected-warning{{result unused}} 76 77 void (HasMembers::*pmgv)() = &HasMembers::g; 78 void (HasMembers::*pmgi)(int) = &HasMembers::g; 79 void (*pmgd)(double) = &HasMembers::g; 80 81 void (HasMembers::*pmd)() = &HasMembers::d; 82 } 83 84 struct Incomplete; 85 86 void h() { 87 HasMembers hm, *phm = &hm; 88 89 int HasMembers::*pi = &HasMembers::i; 90 hm.*pi = 0; 91 int i = phm->*pi; 92 (void)&(hm.*pi); 93 (void)&(phm->*pi); 94 (void)&((&hm)->*pi); // expected-error {{address expression must be an lvalue or a function designator}} 95 96 void (HasMembers::*pf)() = &HasMembers::f; 97 (hm.*pf)(); 98 (phm->*pf)(); 99 100 (void)(hm->*pi); // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'struct HasMembers'}} 101 (void)(phm.*pi); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'struct HasMembers *'}} 102 (void)(i.*pi); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'int'}} 103 int *ptr; 104 (void)(ptr->*pi); // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'int *'}} 105 106 int A::*pai = 0; 107 D d, *pd = &d; 108 (void)(d.*pai); 109 (void)(pd->*pai); 110 F f, *ptrf = &f; 111 (void)(f.*pai); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'struct F'}} 112 (void)(ptrf->*pai); // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'struct F *'}} 113 114 (void)(hm.*i); // expected-error {{pointer-to-member}} 115 (void)(phm->*i); // expected-error {{pointer-to-member}} 116 117 Incomplete *inc; 118 int Incomplete::*pii = 0; 119 (void)(inc->*pii); // okay 120 } 121 122 struct OverloadsPtrMem 123 { 124 int operator ->*(const char *); 125 }; 126 127 void i() { 128 OverloadsPtrMem m; 129 int foo = m->*"Awesome!"; 130 } 131