member-pointer.cpp revision 224605064a4ef87d1c3d35ad1cb363f8b534012b
1f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl// RUN: clang -fsyntax-only -verify %s
2f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl
3f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redlstruct A {};
4f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redlenum B { Dummy };
5f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redlnamespace C {}
64433aafbc2591b82e4ea2fc39c723b21d2497f4dSebastian Redlstruct D : A {};
79e5e4aaf8b8835b552819d68d29b6d94115d8a0bSebastian Redlstruct E : A {};
89e5e4aaf8b8835b552819d68d29b6d94115d8a0bSebastian Redlstruct F : D, E {};
99e5e4aaf8b8835b552819d68d29b6d94115d8a0bSebastian Redlstruct G : virtual D {};
10f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl
11f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redlint A::*pdi1;
12f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redlint (::A::*pdi2);
13f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redlint (A::*pfi)(int);
14f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redl
15f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redlint B::*pbi; // expected-error {{expected a class or namespace}}
16f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redlint C::*pci; // expected-error {{'pci' does not point into a class}}
17f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redlvoid A::*pdv; // expected-error {{'pdv' declared as a member pointer to void}}
18f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redlint& A::*pdr; // expected-error {{'pdr' declared as a pointer to a reference}}
198edef7c31d27fc9d5d163660702a8a7730a0d19fSebastian Redl
208edef7c31d27fc9d5d163660702a8a7730a0d19fSebastian Redlvoid f() {
218edef7c31d27fc9d5d163660702a8a7730a0d19fSebastian Redl  // This requires tentative parsing.
228edef7c31d27fc9d5d163660702a8a7730a0d19fSebastian Redl  int (A::*pf)(int, int);
234433aafbc2591b82e4ea2fc39c723b21d2497f4dSebastian Redl
244433aafbc2591b82e4ea2fc39c723b21d2497f4dSebastian Redl  // Implicit conversion to bool.
254433aafbc2591b82e4ea2fc39c723b21d2497f4dSebastian Redl  bool b = pdi1;
264433aafbc2591b82e4ea2fc39c723b21d2497f4dSebastian Redl  b = pfi;
274433aafbc2591b82e4ea2fc39c723b21d2497f4dSebastian Redl
284433aafbc2591b82e4ea2fc39c723b21d2497f4dSebastian Redl  // Conversion from null pointer constant.
294433aafbc2591b82e4ea2fc39c723b21d2497f4dSebastian Redl  pf = 0;
304433aafbc2591b82e4ea2fc39c723b21d2497f4dSebastian Redl  pf = __null;
314433aafbc2591b82e4ea2fc39c723b21d2497f4dSebastian Redl
324433aafbc2591b82e4ea2fc39c723b21d2497f4dSebastian Redl  // Conversion to member of derived.
334433aafbc2591b82e4ea2fc39c723b21d2497f4dSebastian Redl  int D::*pdid = pdi1;
344433aafbc2591b82e4ea2fc39c723b21d2497f4dSebastian Redl  pdid = pdi2;
359e5e4aaf8b8835b552819d68d29b6d94115d8a0bSebastian Redl
369e5e4aaf8b8835b552819d68d29b6d94115d8a0bSebastian Redl  // Fail conversion due to ambiguity and virtuality.
379e5e4aaf8b8835b552819d68d29b6d94115d8a0bSebastian Redl  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}}
389e5e4aaf8b8835b552819d68d29b6d94115d8a0bSebastian Redl  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}}
3921593acb933324b439bc68b68e7cc7d1c3e3484dSebastian Redl
4021593acb933324b439bc68b68e7cc7d1c3e3484dSebastian Redl  // Conversion to member of base.
4121593acb933324b439bc68b68e7cc7d1c3e3484dSebastian Redl  pdi1 = pdid; // expected-error {{incompatible type assigning 'int struct D::*', expected 'int struct A::*'}}
428edef7c31d27fc9d5d163660702a8a7730a0d19fSebastian Redl}
43ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl
4433b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redlstruct TheBase
4533b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl{
4633b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl  void d();
4733b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl};
4833b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl
4933b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redlstruct HasMembers : TheBase
50ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl{
51ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl  int i;
52ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl  void f();
5333b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl
5433b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl  void g();
5533b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl  void g(int);
5633b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl  static void g(double);
57ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl};
58ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl
59ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redlnamespace Fake
60ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl{
61ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl  int i;
62ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl  void f();
63ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl}
64ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl
65ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redlvoid g() {
6633b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl  HasMembers hm;
6733b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl
68ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl  int HasMembers::*pmi = &HasMembers::i;
69ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl  int *pni = &Fake::i;
7033b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl  int *pmii = &hm.i;
71ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl
7233b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl  void (HasMembers::*pmf)() = &HasMembers::f;
73ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl  void (*pnf)() = &Fake::f;
7433b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl  &hm.f; // expected-error {{address expression must be an lvalue or a function designator}}
7533b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl
7633b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl  void (HasMembers::*pmgv)() = &HasMembers::g;
7733b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl  void (HasMembers::*pmgi)(int) = &HasMembers::g;
7833b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl  void (*pmgd)(double) = &HasMembers::g;
7933b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl
8033b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl  void (HasMembers::*pmd)() = &HasMembers::d;
81ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl}
82224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl
83224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redlvoid h() {
84224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl  HasMembers hm, *phm = &hm;
85224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl
86224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl  int HasMembers::*pi = &HasMembers::i;
87224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl  hm.*pi = 0;
88224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl  int i = phm->*pi;
89224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl  (void)&(hm.*pi);
90224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl  (void)&(phm->*pi);
91224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl  (void)&((&hm)->*pi); // expected-error {{address expression must be an lvalue or a function designator}}
92224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl
93224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl  void (HasMembers::*pf)() = &HasMembers::f;
94224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl  (hm.*pf)();
95224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl  (phm->*pf)();
96224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl}
97224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl
98224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redlstruct OverloadsPtrMem
99224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl{
100224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl  int operator ->*(const char *);
101224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl};
102224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl
103224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redlvoid i() {
104224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl  OverloadsPtrMem m;
105224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl  int foo = m->*"Awesome!";
106224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl}
107