Home | History | Annotate | Download | only in SemaCXX
      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 {{cannot create a non-constant pointer to member function}}
     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;
     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   // Okay
    125   Incomplete *inc;
    126   int Incomplete::*pii = 0;
    127   (void)(inc->*pii);
    128 }
    129 
    130 struct OverloadsPtrMem
    131 {
    132   int operator ->*(const char *);
    133 };
    134 
    135 void i() {
    136   OverloadsPtrMem m;
    137   int foo = m->*"Awesome!";
    138 }
    139 
    140 namespace 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 {{cannot create a non-constant pointer to member function}}
    147       p = &(*this).h; // expected-error {{cannot create a non-constant pointer to member function}}
    148     }
    149   };
    150 }
    151 
    152 namespace pr6783 {
    153   struct Base {};
    154   struct X; // expected-note {{forward declaration}}
    155 
    156   int test1(int Base::* p2m, X* object)
    157   {
    158     return object->*p2m; // expected-error {{left hand operand to ->*}}
    159   }
    160 }
    161 
    162 namespace PR7176 {
    163   namespace base
    164   {
    165     struct Process
    166     { };
    167     struct Continuous : Process
    168     {
    169       bool cond();
    170     };
    171   }
    172 
    173   typedef bool( base::Process::*Condition )();
    174 
    175   void m()
    176   { (void)(Condition) &base::Continuous::cond; }
    177 }
    178 
    179 namespace rdar8358512 {
    180   // We can't call this with an overload set because we're not allowed
    181   // to look into overload sets unless the parameter has some kind of
    182   // function type.
    183   template <class F> void bind(F f); // expected-note 12 {{candidate template ignored}}
    184   template <class F, class T> void bindmem(F (T::*f)()); // expected-note 4 {{candidate template ignored}}
    185   template <class F> void bindfn(F (*f)()); // expected-note 4 {{candidate template ignored}}
    186 
    187   struct A {
    188     void nonstat();
    189     void nonstat(int);
    190 
    191     void mixed();
    192     static void mixed(int);
    193 
    194     static void stat();
    195     static void stat(int);
    196 
    197     template <typename T> struct Test0 {
    198       void test() {
    199         bind(&nonstat); // expected-error {{no matching function for call}}
    200         bind(&A::nonstat); // expected-error {{no matching function for call}}
    201 
    202         bind(&mixed); // expected-error {{no matching function for call}}
    203         bind(&A::mixed); // expected-error {{no matching function for call}}
    204 
    205         bind(&stat); // expected-error {{no matching function for call}}
    206         bind(&A::stat); // expected-error {{no matching function for call}}
    207       }
    208     };
    209 
    210     template <typename T> struct Test1 {
    211       void test() {
    212         bindmem(&nonstat); // expected-error {{no matching function for call}}
    213         bindmem(&A::nonstat);
    214 
    215         bindmem(&mixed); // expected-error {{no matching function for call}}
    216         bindmem(&A::mixed);
    217 
    218         bindmem(&stat); // expected-error {{no matching function for call}}
    219         bindmem(&A::stat); // expected-error {{no matching function for call}}
    220       }
    221     };
    222 
    223     template <typename T> struct Test2 {
    224       void test() {
    225         bindfn(&nonstat); // expected-error {{no matching function for call}}
    226         bindfn(&A::nonstat); // expected-error {{no matching function for call}}
    227 
    228         bindfn(&mixed); // expected-error {{no matching function for call}}
    229         bindfn(&A::mixed); // expected-error {{no matching function for call}}
    230 
    231         bindfn(&stat);
    232         bindfn(&A::stat);
    233       }
    234     };
    235   };
    236 
    237   template <class T> class B {
    238     void nonstat();
    239     void nonstat(int);
    240 
    241     void mixed();
    242     static void mixed(int);
    243 
    244     static void stat();
    245     static void stat(int);
    246 
    247     // None of these can be diagnosed yet, because the arguments are
    248     // still dependent.
    249     void test0a() {
    250       bind(&nonstat);
    251       bind(&B::nonstat);
    252 
    253       bind(&mixed);
    254       bind(&B::mixed);
    255 
    256       bind(&stat);
    257       bind(&B::stat);
    258     }
    259 
    260     void test0b() {
    261       bind(&nonstat); // expected-error {{no matching function for call}}
    262       bind(&B::nonstat); // expected-error {{no matching function for call}}
    263 
    264       bind(&mixed); // expected-error {{no matching function for call}}
    265       bind(&B::mixed); // expected-error {{no matching function for call}}
    266 
    267       bind(&stat); // expected-error {{no matching function for call}}
    268       bind(&B::stat); // expected-error {{no matching function for call}}
    269     }
    270   };
    271 
    272   template void B<int>::test0b(); // expected-note {{in instantiation}}
    273 }
    274 
    275 namespace PR9973 {
    276   template<class R, class T> struct dm
    277   {
    278     typedef R T::*F;
    279     F f_;
    280     template<class U> int & call(U u)
    281     { 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'}}
    282 
    283     template<class U> int operator()(U u)
    284     { call(u); } // expected-note{{in instantiation of}}
    285   };
    286 
    287   template<class R, class T>
    288   dm<R, T> mem_fn(R T::*) ;
    289 
    290   struct test
    291   { int nullary_v(); };
    292 
    293   void f()
    294   {
    295     test* t;
    296     mem_fn(&test::nullary_v)(t); // expected-note{{in instantiation of}}
    297   }
    298 }
    299 
    300 namespace test8 {
    301   struct A { int foo; };
    302   int test1() {
    303     // Verify that we perform (and check) an lvalue conversion on the operands here.
    304     return (*((A**) 0)) // expected-warning {{indirection of non-volatile null pointer will be deleted}} expected-note {{consider}}
    305              ->**(int A::**) 0; // expected-warning {{indirection of non-volatile null pointer will be deleted}} expected-note {{consider}}
    306   }
    307 
    308   int test2() {
    309     // Verify that we perform (and check) an lvalue conversion on the operands here.
    310     // TODO: the .* should itself warn about being a dereference of null.
    311     return (*((A*) 0))
    312              .**(int A::**) 0; // expected-warning {{indirection of non-volatile null pointer will be deleted}} expected-note {{consider}}
    313   }
    314 }
    315