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