blob: 3d9d5b5ebbbc5f537a72434f65080b93991b3c06 [file] [log] [blame]
Daniel Dunbara5728872009-12-15 20:14:24 +00001// RUN: %clang_cc1 -fsyntax-only -verify %s
Sebastian Redlf30208a2009-01-24 21:16:55 +00002
3struct A {};
4enum B { Dummy };
5namespace C {}
Sebastian Redl4433aaf2009-01-25 19:43:20 +00006struct D : A {};
Sebastian Redl9e5e4aa2009-01-26 19:54:48 +00007struct E : A {};
8struct F : D, E {};
9struct G : virtual D {};
Sebastian Redlf30208a2009-01-24 21:16:55 +000010
11int A::*pdi1;
12int (::A::*pdi2);
13int (A::*pfi)(int);
14
Douglas Gregor949bf692009-06-09 22:17:39 +000015int B::*pbi; // expected-error {{expected a class or namespace}} \
16 // expected-error{{does not point into a class}}
Sebastian Redlf30208a2009-01-24 21:16:55 +000017int C::*pci; // expected-error {{'pci' does not point into a class}}
18void A::*pdv; // expected-error {{'pdv' declared as a member pointer to void}}
Anders Carlsson8d4655d2009-06-30 00:06:57 +000019int& A::*pdr; // expected-error {{'pdr' declared as a member pointer to a reference}}
Sebastian Redl8edef7c2009-01-24 23:29:36 +000020
21void f() {
22 // This requires tentative parsing.
23 int (A::*pf)(int, int);
Sebastian Redl4433aaf2009-01-25 19:43:20 +000024
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;
Sebastian Redl9e5e4aa2009-01-26 19:54:48 +000036
37 // Fail conversion due to ambiguity and virtuality.
Eli Friedmancfdc81a2009-12-19 08:11:05 +000038 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'}}
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}}
Sebastian Redl21593ac2009-01-28 18:33:18 +000040
41 // Conversion to member of base.
42 pdi1 = pdid; // expected-error {{incompatible type assigning 'int struct D::*', expected 'int struct A::*'}}
Douglas Gregor20b3e992009-08-24 17:42:35 +000043
44 // Comparisons
45 int (A::*pf2)(int, int);
46 int (D::*pf3)(int, int) = 0;
47 bool b1 = (pf == pf2); (void)b1;
48 bool b2 = (pf != pf2); (void)b2;
49 bool b3 = (pf == pf3); (void)b3;
50 bool b4 = (pf != 0); (void)b4;
Sebastian Redl8edef7c2009-01-24 23:29:36 +000051}
Sebastian Redlebc07d52009-02-03 20:19:35 +000052
Sebastian Redl33b399a2009-02-04 21:23:32 +000053struct TheBase
54{
55 void d();
56};
57
58struct HasMembers : TheBase
Sebastian Redlebc07d52009-02-03 20:19:35 +000059{
60 int i;
61 void f();
Sebastian Redl33b399a2009-02-04 21:23:32 +000062
63 void g();
64 void g(int);
65 static void g(double);
Sebastian Redlebc07d52009-02-03 20:19:35 +000066};
67
68namespace Fake
69{
70 int i;
71 void f();
72}
73
74void g() {
Sebastian Redl33b399a2009-02-04 21:23:32 +000075 HasMembers hm;
76
Sebastian Redlebc07d52009-02-03 20:19:35 +000077 int HasMembers::*pmi = &HasMembers::i;
78 int *pni = &Fake::i;
Sebastian Redl33b399a2009-02-04 21:23:32 +000079 int *pmii = &hm.i;
Sebastian Redlebc07d52009-02-03 20:19:35 +000080
Sebastian Redl33b399a2009-02-04 21:23:32 +000081 void (HasMembers::*pmf)() = &HasMembers::f;
Sebastian Redlebc07d52009-02-03 20:19:35 +000082 void (*pnf)() = &Fake::f;
Sebastian Redle27d87f2010-01-11 15:56:56 +000083 &hm.f; // expected-error {{must explicitly qualify}} expected-warning{{result unused}}
Sebastian Redl33b399a2009-02-04 21:23:32 +000084
85 void (HasMembers::*pmgv)() = &HasMembers::g;
86 void (HasMembers::*pmgi)(int) = &HasMembers::g;
87 void (*pmgd)(double) = &HasMembers::g;
88
89 void (HasMembers::*pmd)() = &HasMembers::d;
Sebastian Redlebc07d52009-02-03 20:19:35 +000090}
Sebastian Redl22460502009-02-07 00:15:38 +000091
Douglas Gregor3f5b61c2009-05-14 00:28:11 +000092struct Incomplete;
Sebastian Redl7878ffd2009-02-07 00:41:42 +000093
Sebastian Redl22460502009-02-07 00:15:38 +000094void h() {
95 HasMembers hm, *phm = &hm;
96
97 int HasMembers::*pi = &HasMembers::i;
98 hm.*pi = 0;
99 int i = phm->*pi;
100 (void)&(hm.*pi);
101 (void)&(phm->*pi);
Fariborz Jahanian27d4be52009-10-08 18:00:39 +0000102 (void)&((&hm)->*pi);
Sebastian Redl22460502009-02-07 00:15:38 +0000103
104 void (HasMembers::*pf)() = &HasMembers::f;
105 (hm.*pf)();
106 (phm->*pf)();
Sebastian Redl7878ffd2009-02-07 00:41:42 +0000107
108 (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'}}
109 (void)(phm.*pi); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'struct HasMembers *'}}
110 (void)(i.*pi); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'int'}}
111 int *ptr;
112 (void)(ptr->*pi); // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'int *'}}
113
114 int A::*pai = 0;
115 D d, *pd = &d;
116 (void)(d.*pai);
117 (void)(pd->*pai);
118 F f, *ptrf = &f;
119 (void)(f.*pai); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'struct F'}}
120 (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 *'}}
121
Douglas Gregore7450f52009-03-24 19:52:54 +0000122 (void)(hm.*i); // expected-error {{pointer-to-member}}
123 (void)(phm->*i); // expected-error {{pointer-to-member}}
Sebastian Redl7878ffd2009-02-07 00:41:42 +0000124
125 Incomplete *inc;
126 int Incomplete::*pii = 0;
Douglas Gregor3f5b61c2009-05-14 00:28:11 +0000127 (void)(inc->*pii); // okay
Sebastian Redl22460502009-02-07 00:15:38 +0000128}
129
130struct OverloadsPtrMem
131{
132 int operator ->*(const char *);
133};
134
135void i() {
136 OverloadsPtrMem m;
137 int foo = m->*"Awesome!";
138}
Sebastian Redle27d87f2010-01-11 15:56:56 +0000139
140namespace pr5985 {
141 struct c {
142 void h();
143 void f() {
144 void (c::*p)();
145 p = &h; // expected-error {{must explicitly qualify}}
146 p = &this->h; // expected-error {{must explicitly qualify}}
147 p = &(*this).h; // expected-error {{must explicitly qualify}}
148 }
149 };
150}