433 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify %std_cxx98- %s2 3struct A {};4enum B { Dummy };5namespace C {}6struct D : A {};7struct E : A {};8struct F : D, E {};9struct G : virtual D {};10class H : A {}; // expected-note 2{{implicitly declared private here}}11 12int A::*pdi1;13int (::A::*pdi2);14int (A::*pfi)(int);15void (*A::*ppfie)() throw();16#if __cplusplus < 201703L17// expected-error@-2 {{exception specifications are not allowed beyond a single level of indirection}}18#endif19 20int B::*pbi;21#if __cplusplus <= 199711L // C++03 or earlier modes22// expected-warning@-2 {{use of enumeration in a nested name specifier is a C++11 extension}}23#endif24// expected-error@-4 {{'pbi' does not point into a class}}25int C::*pci; // expected-error {{'pci' does not point into a class}}26void A::*pdv; // expected-error {{'pdv' declared as a member pointer to void}}27int& A::*pdr; // expected-error {{'pdr' declared as a member pointer to a reference}}28 29void f() {30 // This requires tentative parsing.31 int (A::*pf)(int, int);32 33 // Implicit conversion to bool.34 bool b = pdi1;35 b = pfi;36 37 // Conversion from null pointer constant.38 pf = 0;39 pf = __null;40 41 // Conversion to member of derived.42 int D::*pdid = pdi1;43 pdid = pdi2;44 45 // Fail conversion due to ambiguity and virtuality.46 int F::*pdif = pdi1; // expected-error {{ambiguous conversion from pointer to member of base class 'A' to pointer to member of derived class 'F':}}47 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}}48 49 // Conversion to member of base.50 pdi1 = pdid; // expected-error {{assigning to 'int A::*' from incompatible type 'int D::*'}}51 52 // Comparisons53 int (A::*pf2)(int, int);54 int (D::*pf3)(int, int) = 0;55 bool b1 = (pf == pf2); (void)b1;56 bool b2 = (pf != pf2); (void)b2;57 bool b3 = (pf == pf3); (void)b3;58 bool b4 = (pf != 0); (void)b4;59}60 61struct TheBase62{63 void d();64};65 66struct HasMembers : TheBase67{68 int i;69 void f();70 71 void g();72 void g(int);73 static void g(double);74};75 76namespace Fake77{78 int i;79 void f();80}81 82void g() {83 HasMembers hm;84 85 int HasMembers::*pmi = &HasMembers::i;86 int *pni = &Fake::i;87 int *pmii = &hm.i;88 89 void (HasMembers::*pmf)() = &HasMembers::f;90 void (*pnf)() = &Fake::f;91 &hm.f; // expected-error {{cannot create a non-constant pointer to member function}}92 93 void (HasMembers::*pmgv)() = &HasMembers::g;94 void (HasMembers::*pmgi)(int) = &HasMembers::g;95 void (*pmgd)(double) = &HasMembers::g;96 97 void (HasMembers::*pmd)() = &HasMembers::d;98}99 100struct Incomplete;101 102void h() {103 HasMembers hm, *phm = &hm;104 105 int HasMembers::*pi = &HasMembers::i;106 hm.*pi = 0;107 int i = phm->*pi;108 (void)&(hm.*pi);109 (void)&(phm->*pi);110 (void)&((&hm)->*pi);111 112 void (HasMembers::*pf)() = &HasMembers::f;113 (hm.*pf)();114 (phm->*pf)();115 116 (void)(hm->*pi); // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'HasMembers'}}117 (void)(phm.*pi); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'HasMembers *'}}118 (void)(i.*pi); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'int'}}119 int *ptr;120 (void)(ptr->*pi); // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'int *'}}121 122 int A::*pai = 0;123 D d, *pd = &d;124 (void)(d.*pai);125 (void)(pd->*pai);126 F f, *ptrf = &f;127 (void)(f.*pai); // expected-error {{ambiguous conversion from derived class 'F' to base class 'A'}}128 (void)(ptrf->*pai); // expected-error {{ambiguous conversion from derived class 'F' to base class 'A'}}129 H h, *ptrh = &h;130 (void)(h.*pai); // expected-error {{cannot cast 'H' to its private base class 'A'}}131 (void)(ptrh->*pai); // expected-error {{cannot cast 'H' to its private base class 'A'}}132 133 (void)(hm.*i); // expected-error {{pointer-to-member}}134 (void)(phm->*i); // expected-error {{pointer-to-member}}135 136 // Okay137 Incomplete *inc;138 int Incomplete::*pii = 0;139 (void)(inc->*pii);140}141 142struct OverloadsPtrMem143{144 int operator ->*(const char *);145};146 147void i() {148 OverloadsPtrMem m;149 int foo = m->*"Awesome!";150}151 152namespace pr5985 {153 struct c {154 void h();155 void f() {156 void (c::*p)();157 p = &h; // expected-error {{must explicitly qualify}}158 p = &this->h; // expected-error {{cannot create a non-constant pointer to member function}}159 p = &(*this).h; // expected-error {{cannot create a non-constant pointer to member function}}160 }161 };162}163 164namespace pr6783 {165 struct Base {};166 struct X; // expected-note {{forward declaration}}167 168 int test1(int Base::* p2m, X* object)169 {170 return object->*p2m; // expected-error {{left hand operand to ->*}}171 }172}173 174namespace PR7176 {175 namespace base176 {177 struct Process178 { };179 struct Continuous : Process180 {181 bool cond();182 };183 }184 185 typedef bool( base::Process::*Condition )();186 187 void m()188 { (void)(Condition) &base::Continuous::cond; }189}190 191namespace rdar8358512 {192 // We can't call this with an overload set because we're not allowed193 // to look into overload sets unless the parameter has some kind of194 // function type.195 template <class F> void bind(F f); // expected-note 12 {{candidate template ignored}}196 template <class F, class T> void bindmem(F (T::*f)()); // expected-note 4 {{candidate template ignored}}197 template <class F> void bindfn(F (*f)()); // expected-note 4 {{candidate template ignored}}198 199 struct A {200 void nonstat();201 void nonstat(int);202 203 void mixed();204 static void mixed(int);205 206 static void stat();207 static void stat(int);208 209 template <typename T> struct Test0 {210 void test() {211 bind(&nonstat); // expected-error {{no matching function for call}}212 bind(&A::nonstat); // expected-error {{no matching function for call}}213 214 bind(&mixed); // expected-error {{no matching function for call}}215 bind(&A::mixed); // expected-error {{no matching function for call}}216 217 bind(&stat); // expected-error {{no matching function for call}}218 bind(&A::stat); // expected-error {{no matching function for call}}219 }220 };221 222 template <typename T> struct Test1 {223 void test() {224 bindmem(&nonstat); // expected-error {{no matching function for call}}225 bindmem(&A::nonstat);226 227 bindmem(&mixed); // expected-error {{no matching function for call}}228 bindmem(&A::mixed);229 230 bindmem(&stat); // expected-error {{no matching function for call}}231 bindmem(&A::stat); // expected-error {{no matching function for call}}232 }233 };234 235 template <typename T> struct Test2 {236 void test() {237 bindfn(&nonstat); // expected-error {{no matching function for call}}238 bindfn(&A::nonstat); // expected-error {{no matching function for call}}239 240 bindfn(&mixed); // expected-error {{no matching function for call}}241 bindfn(&A::mixed); // expected-error {{no matching function for call}}242 243 bindfn(&stat);244 bindfn(&A::stat);245 }246 };247 };248 249 template <class T> class B {250 void nonstat();251 void nonstat(int);252 253 void mixed();254 static void mixed(int);255 256 static void stat();257 static void stat(int);258 259 // None of these can be diagnosed yet, because the arguments are260 // still dependent.261 void test0a() {262 bind(&nonstat);263 bind(&B::nonstat);264 265 bind(&mixed);266 bind(&B::mixed);267 268 bind(&stat);269 bind(&B::stat);270 }271 272 void test0b() {273 bind(&nonstat); // expected-error {{no matching function for call}}274 bind(&B::nonstat); // expected-error {{no matching function for call}}275 276 bind(&mixed); // expected-error {{no matching function for call}}277 bind(&B::mixed); // expected-error {{no matching function for call}}278 279 bind(&stat); // expected-error {{no matching function for call}}280 bind(&B::stat); // expected-error {{no matching function for call}}281 }282 };283 284 template void B<int>::test0b(); // expected-note {{in instantiation}}285}286 287namespace PR9973 {288 template<class R, class T> struct dm289 {290 typedef R T::*F;291 F f_;292 template<class U> int & call(U u)293 { 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'}}294 295 template<class U> int operator()(U u)296 { call(u); } // expected-note{{in instantiation of}}297 };298 299 template<class R, class T>300 dm<R, T> mem_fn(R T::*) ;301 302 struct test303 { int nullary_v(); };304 305 void f()306 {307 test* t;308 mem_fn(&test::nullary_v)(t); // expected-note{{in instantiation of}}309 }310}311 312namespace test8 {313 struct A { int foo; };314 int test1() {315 // Verify that we perform (and check) an lvalue conversion on the operands here.316 return (*((A**) 0)) // expected-warning {{indirection of non-volatile null pointer will be deleted}} expected-note {{consider}}317 ->**(int A::**) 0; // expected-warning {{indirection of non-volatile null pointer will be deleted}} expected-note {{consider}}318 }319 320 int test2() {321 // Verify that we perform (and check) an lvalue conversion on the operands here.322 // TODO: the .* should itself warn about being a dereference of null.323 return (*((A*) 0))324 .**(int A::**) 0; // expected-warning {{indirection of non-volatile null pointer will be deleted}} expected-note {{consider}}325 }326}327 328namespace test9 {329 struct FOO BAR;330 // expected-error@-1 {{variable has incomplete type 'struct FOO'}}331 // expected-note@-2 {{forward declaration of 'test9::FOO'}}332 // expected-note@-3 {{'BAR' declared here}}333 struct C { int BAR::*mp; };334 // expected-error@-1 {{'BAR' is not a class, namespace, or enumeration}}335} // namespace test9336 337namespace GH132494 {338 enum E {};339 340 void f(int E::*); // expected-error {{member pointer does not point into a class}}341 342 template <class T> struct A {343 int T::*foo; // expected-error {{'foo' does not point into a class}}344 };345 template struct A<E>; // expected-note {{requested here}}346} // namespace GH132494347 348namespace GH132401 {349 template <typename Func> struct CallableHelper {350 static auto Resolve() -> Func;351 };352 struct QIODevice {353 void d_func() { (void)d_ptr; }354 int d_ptr;355 };356 template struct CallableHelper<void (QIODevice::*)()>;357} // namespace GH132401358 359namespace adl_dependent_class {360 struct A {361 template <class T> A(T);362 };363 struct C;364 template <class T> void d(void (T::*)());365 void f(A);366 void g() { f(d<C>); }367} // namespace adl_dependent_class368 369namespace deduction1 {370 template <typename> struct RunCallImpl;371 372 template <typename Derived>373 struct RunCallImpl<int (Derived::Info::*)(Derived *)> {};374 375 template <typename d>376 void RunCall(d) {377 RunCallImpl<d>();378 }379 380 struct Filter {381 virtual void MakeCall();382 virtual ~Filter() = default;383 };384 385 template <typename Derived>386 struct ImplementFilter : Filter {387 void MakeCall() { RunCall(&Derived::Info::OnStuffHandler); }388 };389 390 struct FoobarFilter : ImplementFilter<FoobarFilter> {391 struct Info {392 int OnStuffHandler(FoobarFilter *);393 };394 };395} // namespace deduction1396 397namespace deduction2 {398 template <typename> struct A;399 template <typename T>400 struct A<void (T::C::*)(int &, T *)> {};401 template <typename T> void e(T) {402 A<T> f;403 }404 struct S {405 struct C {406 void h(int &, S *);407 };408 void i() { e(&C::h); }409 };410} // namespace deduction2411 412namespace deduction_qualifiers {413 struct A {414 int v;415 };416 using CA = const A;417 418 template <class T> void g(const T&, int T::*);419 template <class T> void h(const T&, int CA::*);420 421 void test(const A a, A b) {422 g(a, &A::v);423 g(a, &CA::v);424 h(a, &A::v);425 h(a, &CA::v);426 427 g(b, &A::v);428 g(b, &CA::v);429 h(b, &A::v);430 h(b, &CA::v);431 }432} // namespace deduction_qualifiers433