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