member-pointer.cpp revision a5728872c7702ddd09537c95bc3cbd20e1f2fb09
1a5728872c7702ddd09537c95bc3cbd20e1f2fb09Daniel Dunbar// RUN: %clang_cc1 -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
15949bf69136e07fb7968d84bc21d9272ff343ffdbDouglas Gregorint B::*pbi; // expected-error {{expected a class or namespace}} \
16949bf69136e07fb7968d84bc21d9272ff343ffdbDouglas Gregor             // expected-error{{does not point into a class}}
17f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redlint C::*pci; // expected-error {{'pci' does not point into a class}}
18f30208ad5b334e93582e846a2a0c92f38a607b8aSebastian Redlvoid A::*pdv; // expected-error {{'pdv' declared as a member pointer to void}}
198d4655d3b966da02fe0588767160448594cddd61Anders Carlssonint& A::*pdr; // expected-error {{'pdr' declared as a member pointer to a reference}}
208edef7c31d27fc9d5d163660702a8a7730a0d19fSebastian Redl
218edef7c31d27fc9d5d163660702a8a7730a0d19fSebastian Redlvoid f() {
228edef7c31d27fc9d5d163660702a8a7730a0d19fSebastian Redl  // This requires tentative parsing.
238edef7c31d27fc9d5d163660702a8a7730a0d19fSebastian Redl  int (A::*pf)(int, int);
244433aafbc2591b82e4ea2fc39c723b21d2497f4dSebastian Redl
254433aafbc2591b82e4ea2fc39c723b21d2497f4dSebastian Redl  // Implicit conversion to bool.
264433aafbc2591b82e4ea2fc39c723b21d2497f4dSebastian Redl  bool b = pdi1;
274433aafbc2591b82e4ea2fc39c723b21d2497f4dSebastian Redl  b = pfi;
284433aafbc2591b82e4ea2fc39c723b21d2497f4dSebastian Redl
294433aafbc2591b82e4ea2fc39c723b21d2497f4dSebastian Redl  // Conversion from null pointer constant.
304433aafbc2591b82e4ea2fc39c723b21d2497f4dSebastian Redl  pf = 0;
314433aafbc2591b82e4ea2fc39c723b21d2497f4dSebastian Redl  pf = __null;
324433aafbc2591b82e4ea2fc39c723b21d2497f4dSebastian Redl
334433aafbc2591b82e4ea2fc39c723b21d2497f4dSebastian Redl  // Conversion to member of derived.
344433aafbc2591b82e4ea2fc39c723b21d2497f4dSebastian Redl  int D::*pdid = pdi1;
354433aafbc2591b82e4ea2fc39c723b21d2497f4dSebastian Redl  pdid = pdi2;
369e5e4aaf8b8835b552819d68d29b6d94115d8a0bSebastian Redl
379e5e4aaf8b8835b552819d68d29b6d94115d8a0bSebastian Redl  // Fail conversion due to ambiguity and virtuality.
389e5e4aaf8b8835b552819d68d29b6d94115d8a0bSebastian 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}}
399e5e4aaf8b8835b552819d68d29b6d94115d8a0bSebastian 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}}
4021593acb933324b439bc68b68e7cc7d1c3e3484dSebastian Redl
4121593acb933324b439bc68b68e7cc7d1c3e3484dSebastian Redl  // Conversion to member of base.
4221593acb933324b439bc68b68e7cc7d1c3e3484dSebastian Redl  pdi1 = pdid; // expected-error {{incompatible type assigning 'int struct D::*', expected 'int struct A::*'}}
4320b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor
4420b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor  // Comparisons
4520b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor  int (A::*pf2)(int, int);
4620b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor  int (D::*pf3)(int, int) = 0;
4720b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor  bool b1 = (pf == pf2); (void)b1;
4820b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor  bool b2 = (pf != pf2); (void)b2;
4920b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor  bool b3 = (pf == pf3); (void)b3;
5020b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor  bool b4 = (pf != 0); (void)b4;
518edef7c31d27fc9d5d163660702a8a7730a0d19fSebastian Redl}
52ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl
5333b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redlstruct TheBase
5433b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl{
5533b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl  void d();
5633b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl};
5733b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl
5833b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redlstruct HasMembers : TheBase
59ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl{
60ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl  int i;
61ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl  void f();
6233b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl
6333b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl  void g();
6433b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl  void g(int);
6533b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl  static void g(double);
66ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl};
67ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl
68ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redlnamespace Fake
69ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl{
70ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl  int i;
71ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl  void f();
72ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl}
73ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl
74ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redlvoid g() {
7533b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl  HasMembers hm;
7633b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl
77ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl  int HasMembers::*pmi = &HasMembers::i;
78ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl  int *pni = &Fake::i;
7933b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl  int *pmii = &hm.i;
80ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl
8133b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl  void (HasMembers::*pmf)() = &HasMembers::f;
82ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl  void (*pnf)() = &Fake::f;
839895d88c34cb2eab65c622cddeaf721108d1af38Eli Friedman  &hm.f; // FIXME: needs diagnostic expected-warning{{result unused}}
8433b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl
8533b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl  void (HasMembers::*pmgv)() = &HasMembers::g;
8633b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl  void (HasMembers::*pmgi)(int) = &HasMembers::g;
8733b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl  void (*pmgd)(double) = &HasMembers::g;
8833b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl
8933b399a8fdd0910ed86b60e61c6a02ba8258bbe3Sebastian Redl  void (HasMembers::*pmd)() = &HasMembers::d;
90ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl}
91224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl
923f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregorstruct Incomplete;
937878ffde0c48a33a8fd3819be1b797d52f7b3849Sebastian Redl
94224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redlvoid h() {
95224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl  HasMembers hm, *phm = &hm;
96224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl
97224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl  int HasMembers::*pi = &HasMembers::i;
98224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl  hm.*pi = 0;
99224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl  int i = phm->*pi;
100224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl  (void)&(hm.*pi);
101224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl  (void)&(phm->*pi);
10227d4be5b3f455275ff6b6afe5ce155d6435081d7Fariborz Jahanian  (void)&((&hm)->*pi);
103224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl
104224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl  void (HasMembers::*pf)() = &HasMembers::f;
105224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl  (hm.*pf)();
106224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl  (phm->*pf)();
1077878ffde0c48a33a8fd3819be1b797d52f7b3849Sebastian Redl
1087878ffde0c48a33a8fd3819be1b797d52f7b3849Sebastian Redl  (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'}}
1097878ffde0c48a33a8fd3819be1b797d52f7b3849Sebastian Redl  (void)(phm.*pi); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'struct HasMembers *'}}
1107878ffde0c48a33a8fd3819be1b797d52f7b3849Sebastian Redl  (void)(i.*pi); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'int'}}
1117878ffde0c48a33a8fd3819be1b797d52f7b3849Sebastian Redl  int *ptr;
1127878ffde0c48a33a8fd3819be1b797d52f7b3849Sebastian Redl  (void)(ptr->*pi); // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'int *'}}
1137878ffde0c48a33a8fd3819be1b797d52f7b3849Sebastian Redl
1147878ffde0c48a33a8fd3819be1b797d52f7b3849Sebastian Redl  int A::*pai = 0;
1157878ffde0c48a33a8fd3819be1b797d52f7b3849Sebastian Redl  D d, *pd = &d;
1167878ffde0c48a33a8fd3819be1b797d52f7b3849Sebastian Redl  (void)(d.*pai);
1177878ffde0c48a33a8fd3819be1b797d52f7b3849Sebastian Redl  (void)(pd->*pai);
1187878ffde0c48a33a8fd3819be1b797d52f7b3849Sebastian Redl  F f, *ptrf = &f;
1197878ffde0c48a33a8fd3819be1b797d52f7b3849Sebastian Redl  (void)(f.*pai); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'struct F'}}
1207878ffde0c48a33a8fd3819be1b797d52f7b3849Sebastian Redl  (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 *'}}
1217878ffde0c48a33a8fd3819be1b797d52f7b3849Sebastian Redl
122e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor  (void)(hm.*i); // expected-error {{pointer-to-member}}
123e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor  (void)(phm->*i); // expected-error {{pointer-to-member}}
1247878ffde0c48a33a8fd3819be1b797d52f7b3849Sebastian Redl
1257878ffde0c48a33a8fd3819be1b797d52f7b3849Sebastian Redl  Incomplete *inc;
1267878ffde0c48a33a8fd3819be1b797d52f7b3849Sebastian Redl  int Incomplete::*pii = 0;
1273f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor  (void)(inc->*pii); // okay
128224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl}
129224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl
130224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redlstruct OverloadsPtrMem
131224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl{
132224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl  int operator ->*(const char *);
133224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl};
134224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl
135224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redlvoid i() {
136224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl  OverloadsPtrMem m;
137224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl  int foo = m->*"Awesome!";
138224605064a4ef87d1c3d35ad1cb363f8b534012bSebastian Redl}
139