xref: /minix3/external/bsd/llvm/dist/clang/test/SemaCXX/member-pointer.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc // RUN: %clang_cc1 -fsyntax-only -verify %s
2f4a2713aSLionel Sambuc 
3f4a2713aSLionel Sambuc struct A {};
4f4a2713aSLionel Sambuc enum B { Dummy };
5f4a2713aSLionel Sambuc namespace C {}
6f4a2713aSLionel Sambuc struct D : A {};
7f4a2713aSLionel Sambuc struct E : A {};
8f4a2713aSLionel Sambuc struct F : D, E {};
9f4a2713aSLionel Sambuc struct G : virtual D {};
10*0a6a1f1dSLionel Sambuc class H : A {}; // expected-note 2{{implicitly declared private here}}
11f4a2713aSLionel Sambuc 
12f4a2713aSLionel Sambuc int A::*pdi1;
13f4a2713aSLionel Sambuc int (::A::*pdi2);
14f4a2713aSLionel Sambuc int (A::*pfi)(int);
15f4a2713aSLionel Sambuc 
16*0a6a1f1dSLionel Sambuc int B::*pbi; // expected-error {{'B' is not a class, namespace, or scoped enumeration}}
17f4a2713aSLionel Sambuc int C::*pci; // expected-error {{'pci' does not point into a class}}
18f4a2713aSLionel Sambuc void A::*pdv; // expected-error {{'pdv' declared as a member pointer to void}}
19f4a2713aSLionel Sambuc int& A::*pdr; // expected-error {{'pdr' declared as a member pointer to a reference}}
20f4a2713aSLionel Sambuc 
f()21f4a2713aSLionel Sambuc void f() {
22f4a2713aSLionel Sambuc   // This requires tentative parsing.
23f4a2713aSLionel Sambuc   int (A::*pf)(int, int);
24f4a2713aSLionel Sambuc 
25f4a2713aSLionel Sambuc   // Implicit conversion to bool.
26f4a2713aSLionel Sambuc   bool b = pdi1;
27f4a2713aSLionel Sambuc   b = pfi;
28f4a2713aSLionel Sambuc 
29f4a2713aSLionel Sambuc   // Conversion from null pointer constant.
30f4a2713aSLionel Sambuc   pf = 0;
31f4a2713aSLionel Sambuc   pf = __null;
32f4a2713aSLionel Sambuc 
33f4a2713aSLionel Sambuc   // Conversion to member of derived.
34f4a2713aSLionel Sambuc   int D::*pdid = pdi1;
35f4a2713aSLionel Sambuc   pdid = pdi2;
36f4a2713aSLionel Sambuc 
37f4a2713aSLionel Sambuc   // Fail conversion due to ambiguity and virtuality.
38f4a2713aSLionel Sambuc   int F::*pdif = pdi1; // expected-error {{ambiguous conversion from pointer to member of base class 'A' to pointer to member of derived class 'F':}}
39f4a2713aSLionel Sambuc   int G::*pdig = pdi1; // expected-error {{conversion from pointer to member of class 'A' to pointer to member of class 'G' via virtual base 'D' is not allowed}}
40f4a2713aSLionel Sambuc 
41f4a2713aSLionel Sambuc   // Conversion to member of base.
42f4a2713aSLionel Sambuc   pdi1 = pdid; // expected-error {{assigning to 'int A::*' from incompatible type 'int D::*'}}
43f4a2713aSLionel Sambuc 
44f4a2713aSLionel Sambuc   // Comparisons
45f4a2713aSLionel Sambuc   int (A::*pf2)(int, int);
46f4a2713aSLionel Sambuc   int (D::*pf3)(int, int) = 0;
47f4a2713aSLionel Sambuc   bool b1 = (pf == pf2); (void)b1;
48f4a2713aSLionel Sambuc   bool b2 = (pf != pf2); (void)b2;
49f4a2713aSLionel Sambuc   bool b3 = (pf == pf3); (void)b3;
50f4a2713aSLionel Sambuc   bool b4 = (pf != 0); (void)b4;
51f4a2713aSLionel Sambuc }
52f4a2713aSLionel Sambuc 
53f4a2713aSLionel Sambuc struct TheBase
54f4a2713aSLionel Sambuc {
55f4a2713aSLionel Sambuc   void d();
56f4a2713aSLionel Sambuc };
57f4a2713aSLionel Sambuc 
58f4a2713aSLionel Sambuc struct HasMembers : TheBase
59f4a2713aSLionel Sambuc {
60f4a2713aSLionel Sambuc   int i;
61f4a2713aSLionel Sambuc   void f();
62f4a2713aSLionel Sambuc 
63f4a2713aSLionel Sambuc   void g();
64f4a2713aSLionel Sambuc   void g(int);
65f4a2713aSLionel Sambuc   static void g(double);
66f4a2713aSLionel Sambuc };
67f4a2713aSLionel Sambuc 
68f4a2713aSLionel Sambuc namespace Fake
69f4a2713aSLionel Sambuc {
70f4a2713aSLionel Sambuc   int i;
71f4a2713aSLionel Sambuc   void f();
72f4a2713aSLionel Sambuc }
73f4a2713aSLionel Sambuc 
g()74f4a2713aSLionel Sambuc void g() {
75f4a2713aSLionel Sambuc   HasMembers hm;
76f4a2713aSLionel Sambuc 
77f4a2713aSLionel Sambuc   int HasMembers::*pmi = &HasMembers::i;
78f4a2713aSLionel Sambuc   int *pni = &Fake::i;
79f4a2713aSLionel Sambuc   int *pmii = &hm.i;
80f4a2713aSLionel Sambuc 
81f4a2713aSLionel Sambuc   void (HasMembers::*pmf)() = &HasMembers::f;
82f4a2713aSLionel Sambuc   void (*pnf)() = &Fake::f;
83f4a2713aSLionel Sambuc   &hm.f; // expected-error {{cannot create a non-constant pointer to member function}}
84f4a2713aSLionel Sambuc 
85f4a2713aSLionel Sambuc   void (HasMembers::*pmgv)() = &HasMembers::g;
86f4a2713aSLionel Sambuc   void (HasMembers::*pmgi)(int) = &HasMembers::g;
87f4a2713aSLionel Sambuc   void (*pmgd)(double) = &HasMembers::g;
88f4a2713aSLionel Sambuc 
89f4a2713aSLionel Sambuc   void (HasMembers::*pmd)() = &HasMembers::d;
90f4a2713aSLionel Sambuc }
91f4a2713aSLionel Sambuc 
92f4a2713aSLionel Sambuc struct Incomplete;
93f4a2713aSLionel Sambuc 
h()94f4a2713aSLionel Sambuc void h() {
95f4a2713aSLionel Sambuc   HasMembers hm, *phm = &hm;
96f4a2713aSLionel Sambuc 
97f4a2713aSLionel Sambuc   int HasMembers::*pi = &HasMembers::i;
98f4a2713aSLionel Sambuc   hm.*pi = 0;
99f4a2713aSLionel Sambuc   int i = phm->*pi;
100f4a2713aSLionel Sambuc   (void)&(hm.*pi);
101f4a2713aSLionel Sambuc   (void)&(phm->*pi);
102f4a2713aSLionel Sambuc   (void)&((&hm)->*pi);
103f4a2713aSLionel Sambuc 
104f4a2713aSLionel Sambuc   void (HasMembers::*pf)() = &HasMembers::f;
105f4a2713aSLionel Sambuc   (hm.*pf)();
106f4a2713aSLionel Sambuc   (phm->*pf)();
107f4a2713aSLionel Sambuc 
108f4a2713aSLionel Sambuc   (void)(hm->*pi); // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'HasMembers'}}
109f4a2713aSLionel Sambuc   (void)(phm.*pi); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'HasMembers *'}}
110f4a2713aSLionel Sambuc   (void)(i.*pi); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'int'}}
111f4a2713aSLionel Sambuc   int *ptr;
112f4a2713aSLionel Sambuc   (void)(ptr->*pi); // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'int *'}}
113f4a2713aSLionel Sambuc 
114f4a2713aSLionel Sambuc   int A::*pai = 0;
115f4a2713aSLionel Sambuc   D d, *pd = &d;
116f4a2713aSLionel Sambuc   (void)(d.*pai);
117f4a2713aSLionel Sambuc   (void)(pd->*pai);
118f4a2713aSLionel Sambuc   F f, *ptrf = &f;
119*0a6a1f1dSLionel Sambuc   (void)(f.*pai); // expected-error {{ambiguous conversion from derived class 'F' to base class 'A'}}
120*0a6a1f1dSLionel Sambuc   (void)(ptrf->*pai); // expected-error {{ambiguous conversion from derived class 'F' to base class 'A'}}
121*0a6a1f1dSLionel Sambuc   H h, *ptrh = &h;
122*0a6a1f1dSLionel Sambuc   (void)(h.*pai); // expected-error {{cannot cast 'H' to its private base class 'A'}}
123*0a6a1f1dSLionel Sambuc   (void)(ptrh->*pai); // expected-error {{cannot cast 'H' to its private base class 'A'}}
124f4a2713aSLionel Sambuc 
125f4a2713aSLionel Sambuc   (void)(hm.*i); // expected-error {{pointer-to-member}}
126f4a2713aSLionel Sambuc   (void)(phm->*i); // expected-error {{pointer-to-member}}
127f4a2713aSLionel Sambuc 
128f4a2713aSLionel Sambuc   // Okay
129f4a2713aSLionel Sambuc   Incomplete *inc;
130f4a2713aSLionel Sambuc   int Incomplete::*pii = 0;
131f4a2713aSLionel Sambuc   (void)(inc->*pii);
132f4a2713aSLionel Sambuc }
133f4a2713aSLionel Sambuc 
134f4a2713aSLionel Sambuc struct OverloadsPtrMem
135f4a2713aSLionel Sambuc {
136f4a2713aSLionel Sambuc   int operator ->*(const char *);
137f4a2713aSLionel Sambuc };
138f4a2713aSLionel Sambuc 
i()139f4a2713aSLionel Sambuc void i() {
140f4a2713aSLionel Sambuc   OverloadsPtrMem m;
141f4a2713aSLionel Sambuc   int foo = m->*"Awesome!";
142f4a2713aSLionel Sambuc }
143f4a2713aSLionel Sambuc 
144f4a2713aSLionel Sambuc namespace pr5985 {
145f4a2713aSLionel Sambuc   struct c {
146f4a2713aSLionel Sambuc     void h();
fpr5985::c147f4a2713aSLionel Sambuc     void f() {
148f4a2713aSLionel Sambuc       void (c::*p)();
149f4a2713aSLionel Sambuc       p = &h; // expected-error {{must explicitly qualify}}
150f4a2713aSLionel Sambuc       p = &this->h; // expected-error {{cannot create a non-constant pointer to member function}}
151f4a2713aSLionel Sambuc       p = &(*this).h; // expected-error {{cannot create a non-constant pointer to member function}}
152f4a2713aSLionel Sambuc     }
153f4a2713aSLionel Sambuc   };
154f4a2713aSLionel Sambuc }
155f4a2713aSLionel Sambuc 
156f4a2713aSLionel Sambuc namespace pr6783 {
157f4a2713aSLionel Sambuc   struct Base {};
158f4a2713aSLionel Sambuc   struct X; // expected-note {{forward declaration}}
159f4a2713aSLionel Sambuc 
test1(int Base::* p2m,X * object)160f4a2713aSLionel Sambuc   int test1(int Base::* p2m, X* object)
161f4a2713aSLionel Sambuc   {
162f4a2713aSLionel Sambuc     return object->*p2m; // expected-error {{left hand operand to ->*}}
163f4a2713aSLionel Sambuc   }
164f4a2713aSLionel Sambuc }
165f4a2713aSLionel Sambuc 
166f4a2713aSLionel Sambuc namespace PR7176 {
167f4a2713aSLionel Sambuc   namespace base
168f4a2713aSLionel Sambuc   {
169f4a2713aSLionel Sambuc     struct Process
170f4a2713aSLionel Sambuc     { };
171f4a2713aSLionel Sambuc     struct Continuous : Process
172f4a2713aSLionel Sambuc     {
173f4a2713aSLionel Sambuc       bool cond();
174f4a2713aSLionel Sambuc     };
175f4a2713aSLionel Sambuc   }
176f4a2713aSLionel Sambuc 
177f4a2713aSLionel Sambuc   typedef bool( base::Process::*Condition )();
178f4a2713aSLionel Sambuc 
m()179f4a2713aSLionel Sambuc   void m()
180f4a2713aSLionel Sambuc   { (void)(Condition) &base::Continuous::cond; }
181f4a2713aSLionel Sambuc }
182f4a2713aSLionel Sambuc 
183f4a2713aSLionel Sambuc namespace rdar8358512 {
184f4a2713aSLionel Sambuc   // We can't call this with an overload set because we're not allowed
185f4a2713aSLionel Sambuc   // to look into overload sets unless the parameter has some kind of
186f4a2713aSLionel Sambuc   // function type.
187f4a2713aSLionel Sambuc   template <class F> void bind(F f); // expected-note 12 {{candidate template ignored}}
188f4a2713aSLionel Sambuc   template <class F, class T> void bindmem(F (T::*f)()); // expected-note 4 {{candidate template ignored}}
189f4a2713aSLionel Sambuc   template <class F> void bindfn(F (*f)()); // expected-note 4 {{candidate template ignored}}
190f4a2713aSLionel Sambuc 
191f4a2713aSLionel Sambuc   struct A {
192f4a2713aSLionel Sambuc     void nonstat();
193f4a2713aSLionel Sambuc     void nonstat(int);
194f4a2713aSLionel Sambuc 
195f4a2713aSLionel Sambuc     void mixed();
196f4a2713aSLionel Sambuc     static void mixed(int);
197f4a2713aSLionel Sambuc 
198f4a2713aSLionel Sambuc     static void stat();
199f4a2713aSLionel Sambuc     static void stat(int);
200f4a2713aSLionel Sambuc 
201f4a2713aSLionel Sambuc     template <typename T> struct Test0 {
testrdar8358512::A::Test0202f4a2713aSLionel Sambuc       void test() {
203f4a2713aSLionel Sambuc         bind(&nonstat); // expected-error {{no matching function for call}}
204f4a2713aSLionel Sambuc         bind(&A::nonstat); // expected-error {{no matching function for call}}
205f4a2713aSLionel Sambuc 
206f4a2713aSLionel Sambuc         bind(&mixed); // expected-error {{no matching function for call}}
207f4a2713aSLionel Sambuc         bind(&A::mixed); // expected-error {{no matching function for call}}
208f4a2713aSLionel Sambuc 
209f4a2713aSLionel Sambuc         bind(&stat); // expected-error {{no matching function for call}}
210f4a2713aSLionel Sambuc         bind(&A::stat); // expected-error {{no matching function for call}}
211f4a2713aSLionel Sambuc       }
212f4a2713aSLionel Sambuc     };
213f4a2713aSLionel Sambuc 
214f4a2713aSLionel Sambuc     template <typename T> struct Test1 {
testrdar8358512::A::Test1215f4a2713aSLionel Sambuc       void test() {
216f4a2713aSLionel Sambuc         bindmem(&nonstat); // expected-error {{no matching function for call}}
217f4a2713aSLionel Sambuc         bindmem(&A::nonstat);
218f4a2713aSLionel Sambuc 
219f4a2713aSLionel Sambuc         bindmem(&mixed); // expected-error {{no matching function for call}}
220f4a2713aSLionel Sambuc         bindmem(&A::mixed);
221f4a2713aSLionel Sambuc 
222f4a2713aSLionel Sambuc         bindmem(&stat); // expected-error {{no matching function for call}}
223f4a2713aSLionel Sambuc         bindmem(&A::stat); // expected-error {{no matching function for call}}
224f4a2713aSLionel Sambuc       }
225f4a2713aSLionel Sambuc     };
226f4a2713aSLionel Sambuc 
227f4a2713aSLionel Sambuc     template <typename T> struct Test2 {
testrdar8358512::A::Test2228f4a2713aSLionel Sambuc       void test() {
229f4a2713aSLionel Sambuc         bindfn(&nonstat); // expected-error {{no matching function for call}}
230f4a2713aSLionel Sambuc         bindfn(&A::nonstat); // expected-error {{no matching function for call}}
231f4a2713aSLionel Sambuc 
232f4a2713aSLionel Sambuc         bindfn(&mixed); // expected-error {{no matching function for call}}
233f4a2713aSLionel Sambuc         bindfn(&A::mixed); // expected-error {{no matching function for call}}
234f4a2713aSLionel Sambuc 
235f4a2713aSLionel Sambuc         bindfn(&stat);
236f4a2713aSLionel Sambuc         bindfn(&A::stat);
237f4a2713aSLionel Sambuc       }
238f4a2713aSLionel Sambuc     };
239f4a2713aSLionel Sambuc   };
240f4a2713aSLionel Sambuc 
241f4a2713aSLionel Sambuc   template <class T> class B {
242f4a2713aSLionel Sambuc     void nonstat();
243f4a2713aSLionel Sambuc     void nonstat(int);
244f4a2713aSLionel Sambuc 
245f4a2713aSLionel Sambuc     void mixed();
246f4a2713aSLionel Sambuc     static void mixed(int);
247f4a2713aSLionel Sambuc 
248f4a2713aSLionel Sambuc     static void stat();
249f4a2713aSLionel Sambuc     static void stat(int);
250f4a2713aSLionel Sambuc 
251f4a2713aSLionel Sambuc     // None of these can be diagnosed yet, because the arguments are
252f4a2713aSLionel Sambuc     // still dependent.
test0a()253f4a2713aSLionel Sambuc     void test0a() {
254f4a2713aSLionel Sambuc       bind(&nonstat);
255f4a2713aSLionel Sambuc       bind(&B::nonstat);
256f4a2713aSLionel Sambuc 
257f4a2713aSLionel Sambuc       bind(&mixed);
258f4a2713aSLionel Sambuc       bind(&B::mixed);
259f4a2713aSLionel Sambuc 
260f4a2713aSLionel Sambuc       bind(&stat);
261f4a2713aSLionel Sambuc       bind(&B::stat);
262f4a2713aSLionel Sambuc     }
263f4a2713aSLionel Sambuc 
test0b()264f4a2713aSLionel Sambuc     void test0b() {
265f4a2713aSLionel Sambuc       bind(&nonstat); // expected-error {{no matching function for call}}
266f4a2713aSLionel Sambuc       bind(&B::nonstat); // expected-error {{no matching function for call}}
267f4a2713aSLionel Sambuc 
268f4a2713aSLionel Sambuc       bind(&mixed); // expected-error {{no matching function for call}}
269f4a2713aSLionel Sambuc       bind(&B::mixed); // expected-error {{no matching function for call}}
270f4a2713aSLionel Sambuc 
271f4a2713aSLionel Sambuc       bind(&stat); // expected-error {{no matching function for call}}
272f4a2713aSLionel Sambuc       bind(&B::stat); // expected-error {{no matching function for call}}
273f4a2713aSLionel Sambuc     }
274f4a2713aSLionel Sambuc   };
275f4a2713aSLionel Sambuc 
276f4a2713aSLionel Sambuc   template void B<int>::test0b(); // expected-note {{in instantiation}}
277f4a2713aSLionel Sambuc }
278f4a2713aSLionel Sambuc 
279f4a2713aSLionel Sambuc namespace PR9973 {
280f4a2713aSLionel Sambuc   template<class R, class T> struct dm
281f4a2713aSLionel Sambuc   {
282f4a2713aSLionel Sambuc     typedef R T::*F;
283f4a2713aSLionel Sambuc     F f_;
callPR9973::dm284f4a2713aSLionel Sambuc     template<class U> int & call(U u)
285f4a2713aSLionel Sambuc     { return u->*f_; } // expected-error{{reference to non-static member function must be called; did you mean to call it with no arguments?}} expected-error {{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}}
286f4a2713aSLionel Sambuc 
operator ()PR9973::dm287f4a2713aSLionel Sambuc     template<class U> int operator()(U u)
288f4a2713aSLionel Sambuc     { call(u); } // expected-note{{in instantiation of}}
289f4a2713aSLionel Sambuc   };
290f4a2713aSLionel Sambuc 
291f4a2713aSLionel Sambuc   template<class R, class T>
292f4a2713aSLionel Sambuc   dm<R, T> mem_fn(R T::*) ;
293f4a2713aSLionel Sambuc 
294f4a2713aSLionel Sambuc   struct test
295f4a2713aSLionel Sambuc   { int nullary_v(); };
296f4a2713aSLionel Sambuc 
f()297f4a2713aSLionel Sambuc   void f()
298f4a2713aSLionel Sambuc   {
299f4a2713aSLionel Sambuc     test* t;
300f4a2713aSLionel Sambuc     mem_fn(&test::nullary_v)(t); // expected-note{{in instantiation of}}
301f4a2713aSLionel Sambuc   }
302f4a2713aSLionel Sambuc }
303f4a2713aSLionel Sambuc 
304f4a2713aSLionel Sambuc namespace test8 {
305f4a2713aSLionel Sambuc   struct A { int foo; };
test1()306f4a2713aSLionel Sambuc   int test1() {
307f4a2713aSLionel Sambuc     // Verify that we perform (and check) an lvalue conversion on the operands here.
308f4a2713aSLionel Sambuc     return (*((A**) 0)) // expected-warning {{indirection of non-volatile null pointer will be deleted}} expected-note {{consider}}
309f4a2713aSLionel Sambuc              ->**(int A::**) 0; // expected-warning {{indirection of non-volatile null pointer will be deleted}} expected-note {{consider}}
310f4a2713aSLionel Sambuc   }
311f4a2713aSLionel Sambuc 
test2()312f4a2713aSLionel Sambuc   int test2() {
313f4a2713aSLionel Sambuc     // Verify that we perform (and check) an lvalue conversion on the operands here.
314f4a2713aSLionel Sambuc     // TODO: the .* should itself warn about being a dereference of null.
315f4a2713aSLionel Sambuc     return (*((A*) 0))
316f4a2713aSLionel Sambuc              .**(int A::**) 0; // expected-warning {{indirection of non-volatile null pointer will be deleted}} expected-note {{consider}}
317f4a2713aSLionel Sambuc   }
318f4a2713aSLionel Sambuc }
319