]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/SemaCXX/member-pointer.cpp
Update clang to r104832.
[FreeBSD/FreeBSD.git] / test / SemaCXX / member-pointer.cpp
1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2
3 struct A {};
4 enum B { Dummy };
5 namespace C {}
6 struct D : A {};
7 struct E : A {};
8 struct F : D, E {};
9 struct G : virtual D {};
10
11 int A::*pdi1;
12 int (::A::*pdi2);
13 int (A::*pfi)(int);
14
15 int B::*pbi; // expected-error {{expected a class or namespace}}
16 int C::*pci; // expected-error {{'pci' does not point into a class}}
17 void A::*pdv; // expected-error {{'pdv' declared as a member pointer to void}}
18 int& A::*pdr; // expected-error {{'pdr' declared as a member pointer to a reference}}
19
20 void f() {
21   // This requires tentative parsing.
22   int (A::*pf)(int, int);
23
24   // Implicit conversion to bool.
25   bool b = pdi1;
26   b = pfi;
27
28   // Conversion from null pointer constant.
29   pf = 0;
30   pf = __null;
31
32   // Conversion to member of derived.
33   int D::*pdid = pdi1;
34   pdid = pdi2;
35
36   // Fail conversion due to ambiguity and virtuality.
37   int F::*pdif = pdi1; // expected-error {{ambiguous conversion from pointer to member of base class 'A' to pointer to member of derived class 'F':}}
38   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}}
39
40   // Conversion to member of base.
41   pdi1 = pdid; // expected-error {{assigning to 'int A::*' from incompatible type 'int D::*'}}
42   
43   // Comparisons
44   int (A::*pf2)(int, int);
45   int (D::*pf3)(int, int) = 0;
46   bool b1 = (pf == pf2); (void)b1;
47   bool b2 = (pf != pf2); (void)b2;
48   bool b3 = (pf == pf3); (void)b3;
49   bool b4 = (pf != 0); (void)b4;
50 }
51
52 struct TheBase
53 {
54   void d();
55 };
56
57 struct HasMembers : TheBase
58 {
59   int i;
60   void f();
61
62   void g();
63   void g(int);
64   static void g(double);
65 };
66
67 namespace Fake
68 {
69   int i;
70   void f();
71 }
72
73 void g() {
74   HasMembers hm;
75
76   int HasMembers::*pmi = &HasMembers::i;
77   int *pni = &Fake::i;
78   int *pmii = &hm.i;
79
80   void (HasMembers::*pmf)() = &HasMembers::f;
81   void (*pnf)() = &Fake::f;
82   &hm.f; // expected-error {{must explicitly qualify}} expected-warning{{result unused}}
83
84   void (HasMembers::*pmgv)() = &HasMembers::g;
85   void (HasMembers::*pmgi)(int) = &HasMembers::g;
86   void (*pmgd)(double) = &HasMembers::g;
87
88   void (HasMembers::*pmd)() = &HasMembers::d;
89 }
90
91 struct Incomplete; // expected-note {{forward declaration}}
92
93 void h() {
94   HasMembers hm, *phm = &hm;
95
96   int HasMembers::*pi = &HasMembers::i;
97   hm.*pi = 0;
98   int i = phm->*pi;
99   (void)&(hm.*pi);
100   (void)&(phm->*pi);
101   (void)&((&hm)->*pi); 
102
103   void (HasMembers::*pf)() = &HasMembers::f;
104   (hm.*pf)();
105   (phm->*pf)();
106
107   (void)(hm->*pi); // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'HasMembers'}}
108   (void)(phm.*pi); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'HasMembers *'}}
109   (void)(i.*pi); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'int'}}
110   int *ptr;
111   (void)(ptr->*pi); // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'int *'}}
112
113   int A::*pai = 0;
114   D d, *pd = &d;
115   (void)(d.*pai);
116   (void)(pd->*pai);
117   F f, *ptrf = &f;
118   (void)(f.*pai); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'F'}}
119   (void)(ptrf->*pai); // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'F *'}}
120
121   (void)(hm.*i); // expected-error {{pointer-to-member}}
122   (void)(phm->*i); // expected-error {{pointer-to-member}}
123
124   Incomplete *inc;
125   int Incomplete::*pii = 0;
126   (void)(inc->*pii); // expected-error {{pointer into incomplete}}
127 }
128
129 struct OverloadsPtrMem
130 {
131   int operator ->*(const char *);
132 };
133
134 void i() {
135   OverloadsPtrMem m;
136   int foo = m->*"Awesome!";
137 }
138
139 namespace pr5985 {
140   struct c {
141     void h();
142     void f() {
143       void (c::*p)();
144       p = &h; // expected-error {{must explicitly qualify}}
145       p = &this->h; // expected-error {{must explicitly qualify}}
146       p = &(*this).h; // expected-error {{must explicitly qualify}}
147     }
148   };
149 }
150
151 namespace pr6783 {
152   struct Base {};
153   struct X; // expected-note {{forward declaration}}
154
155   int test1(int Base::* p2m, X* object)
156   {
157     return object->*p2m; // expected-error {{left hand operand to ->*}}
158   }
159 }
160
161 namespace PR7176 {
162   namespace base
163   {
164     struct Process
165     { };
166     struct Continuous : Process
167     {
168       bool cond();
169     };
170   }
171
172   typedef bool( base::Process::*Condition )();
173
174   void m()
175   { (void)(Condition) &base::Continuous::cond; }
176 }