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