Home | History | Annotate | Download | only in SemaCXX
      1 // RUN: %clang_cc1 -fsyntax-only -fshow-overloads=best -verify -triple x86_64-linux-gnu %s
      2 
      3 struct yes;
      4 struct no;
      5 
      6 struct Short {
      7   operator short();
      8 };
      9 
     10 struct Long {
     11   operator long();
     12 };
     13 
     14 enum E1 { };
     15 struct Enum1 {
     16   operator E1();
     17 };
     18 
     19 enum E2 { };
     20 struct Enum2 {
     21   operator E2();
     22 };
     23 
     24 
     25 struct X {
     26   void f();
     27 };
     28 
     29 typedef void (X::*pmf)();
     30 struct Xpmf {
     31   operator pmf();
     32 };
     33 
     34 yes& islong(long);
     35 yes& islong(unsigned long); // FIXME: shouldn't be needed
     36 no& islong(int);
     37 
     38 void f(Short s, Long l, Enum1 e1, Enum2 e2, Xpmf pmf) {
     39   // C++ [over.built]p8
     40   int i1 = +e1;
     41   int i2 = -e2;
     42 
     43   // C++  [over.built]p10:
     44   int i3 = ~s;
     45   bool b1 = !s;
     46 
     47   // C++ [over.built]p12
     48   (void)static_cast<yes&>(islong(s + l));
     49   (void)static_cast<no&>(islong(s + s));
     50 
     51   // C++ [over.built]p16
     52   (void)(pmf == &X::f);
     53   (void)(pmf == 0);
     54 
     55   // C++ [over.built]p17
     56   (void)static_cast<yes&>(islong(s % l));
     57   (void)static_cast<yes&>(islong(l << s));
     58   (void)static_cast<no&>(islong(s << l));
     59   (void)static_cast<yes&>(islong(e1 % l));
     60   // FIXME: should pass (void)static_cast<no&>(islong(e1 % e2));
     61 }
     62 
     63 struct ShortRef { // expected-note{{candidate function (the implicit copy assignment operator)}}
     64   operator short&();
     65 };
     66 
     67 struct LongRef {
     68   operator volatile long&();
     69 };
     70 
     71 struct XpmfRef { // expected-note{{candidate function (the implicit copy assignment operator)}}
     72   operator pmf&();
     73 };
     74 
     75 struct E2Ref {
     76   operator E2&();
     77 };
     78 
     79 void g(ShortRef sr, LongRef lr, E2Ref e2_ref, XpmfRef pmf_ref) {
     80   // C++ [over.built]p3
     81   short s1 = sr++;
     82 
     83   // C++ [over.built]p3
     84   long l1 = lr--;
     85 
     86   // C++ [over.built]p18
     87   short& sr1 = (sr *= lr);
     88   volatile long& lr1 = (lr *= sr);
     89 
     90   // C++ [over.built]p20:
     91   E2 e2r2;
     92   e2r2 = e2_ref;
     93 
     94   pmf &pmr = (pmf_ref = &X::f); // expected-error{{no viable overloaded '='}}
     95   pmf pmr2;
     96   pmr2 = pmf_ref;
     97 
     98   // C++ [over.built]p22
     99   short& sr2 = (sr %= lr);
    100   volatile long& lr2 = (lr <<= sr);
    101 
    102   bool b1 = (sr && lr) || (sr || lr);
    103 }
    104 
    105 struct VolatileIntPtr {
    106   operator int volatile *();
    107 };
    108 
    109 struct ConstIntPtr {
    110   operator int const *();
    111 };
    112 
    113 struct VolatileIntPtrRef {
    114   operator int volatile *&();
    115 };
    116 
    117 struct ConstIntPtrRef {
    118   operator int const *&();
    119 };
    120 
    121 void test_with_ptrs(VolatileIntPtr vip, ConstIntPtr cip, ShortRef sr,
    122                     VolatileIntPtrRef vipr, ConstIntPtrRef cipr) {
    123   const int& cir1 = cip[sr];
    124   const int& cir2 = sr[cip];
    125   volatile int& vir1 = vip[sr];
    126   volatile int& vir2 = sr[vip];
    127   bool b1 = (vip == cip);
    128   long p1 = vip - cip;
    129 
    130   // C++ [over.built]p5:
    131   int volatile *vip1 = vipr++;
    132   int const *cip1 = cipr++;
    133   int volatile *&vipr1 = ++vipr;
    134   int const *&cipr1 = --cipr;
    135 
    136   // C++ [over.built]p6:
    137   int volatile &ivr = *vip;
    138 
    139   // C++ [over.built]p8:
    140   int volatile *vip2 = +vip;
    141   int i1 = +sr;
    142   int i2 = -sr;
    143 
    144   // C++ [over.built]p13:
    145   int volatile &ivr2 = vip[17];
    146   int const &icr2 = 17[cip];
    147 }
    148 
    149 // C++ [over.match.open]p4
    150 
    151 void test_assign_restrictions(ShortRef& sr) {
    152   sr = (short)0; // expected-error{{no viable overloaded '='}}
    153 }
    154 
    155 struct Base { };
    156 struct Derived1 : Base { };
    157 struct Derived2 : Base { };
    158 
    159 template<typename T>
    160 struct ConvertibleToPtrOf {
    161   operator T*();
    162 };
    163 
    164 bool test_with_base_ptrs(ConvertibleToPtrOf<Derived1> d1,
    165                          ConvertibleToPtrOf<Derived2> d2) {
    166   return d1 == d2; // expected-error{{invalid operands}}
    167 }
    168 
    169 // DR425
    170 struct A {
    171   template< typename T > operator T() const;
    172 };
    173 
    174 void test_dr425(A a) {
    175   // FIXME: lots of candidates here!
    176   (void)(1.0f * a); // expected-error{{ambiguous}} \
    177                     // expected-note 4{{candidate}} \
    178                     // expected-note {{remaining 117 candidates omitted; pass -fshow-overloads=all to show them}}
    179 }
    180 
    181 // pr5432
    182 enum e {X};
    183 
    184 const int a[][2] = {{1}};
    185 
    186 int test_pr5432() {
    187   return a[X][X];
    188 }
    189 
    190 void f() {
    191   (void)__extension__(A());
    192 }
    193 
    194 namespace PR7319 {
    195   typedef enum { Enum1, Enum2, Enum3 } MyEnum;
    196 
    197   template<typename X> bool operator>(const X &inX1, const X &inX2);
    198 
    199   void f() {
    200     MyEnum e1, e2;
    201     if (e1 > e2) {}
    202   }
    203 }
    204 
    205 namespace PR8477 {
    206   struct Foo {
    207     operator bool();
    208     operator const char *();
    209   };
    210 
    211   bool doit() {
    212     Foo foo;
    213     long long zero = 0;
    214     (void)(foo + zero);
    215     (void)(foo - zero);
    216     (void)(zero + foo);
    217     (void)(zero[foo]);
    218     (void)(foo - foo); // expected-error{{use of overloaded operator '-' is ambiguous}} \
    219     // expected-note 4{{built-in candidate operator-}} \
    220     // expected-note{{candidates omitted}}
    221     return foo[zero] == zero;
    222   }
    223 }
    224 
    225 namespace PR7851 {
    226   struct X {
    227     operator const void *() const;
    228     operator void *();
    229 
    230     operator const unsigned *() const;
    231     operator unsigned *();
    232   };
    233 
    234   void f() {
    235     X x;
    236     x[0] = 1;
    237     *x = 0;
    238     (void)(x - x);
    239   }
    240 }
    241 
    242 namespace PR12854 {
    243   enum { size = 1 };
    244   void plus_equals() {
    245     int* __restrict py;
    246     py += size;
    247   }
    248 
    249   struct RestrictInt {
    250     operator int* __restrict &();
    251   };
    252 
    253   void user_conversions(RestrictInt ri) {
    254     ++ri;
    255     --ri;
    256     ri++;
    257     ri--;
    258   }
    259 }
    260 
    261 namespace PR12964 {
    262   struct X { operator  __int128() const; } x;
    263   bool a = x == __int128(0);
    264   bool b = x == 0;
    265 
    266   struct Y { operator unsigned __int128() const; } y;
    267   bool c = y == __int128(0);
    268   bool d = y == 0;
    269 
    270   bool e = x == y;
    271 }
    272