1 // RUN: %clang_cc1 -fsyntax-only -fshow-overloads=best -verify %s 2 struct yes; 3 struct no; 4 5 struct Short { 6 operator short(); 7 }; 8 9 struct Long { 10 operator long(); 11 }; 12 13 enum E1 { }; 14 struct Enum1 { 15 operator E1(); 16 }; 17 18 enum E2 { }; 19 struct Enum2 { 20 operator E2(); 21 }; 22 23 24 struct X { 25 void f(); 26 }; 27 28 typedef void (X::*pmf)(); 29 struct Xpmf { 30 operator pmf(); 31 }; 32 33 yes& islong(long); 34 yes& islong(unsigned long); // FIXME: shouldn't be needed 35 no& islong(int); 36 37 void 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 62 struct ShortRef { // expected-note{{candidate function (the implicit copy assignment operator)}} 63 operator short&(); 64 }; 65 66 struct LongRef { 67 operator volatile long&(); 68 }; 69 70 struct XpmfRef { // expected-note{{candidate function (the implicit copy assignment operator)}} 71 operator pmf&(); 72 }; 73 74 struct E2Ref { 75 operator E2&(); 76 }; 77 78 void 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 104 struct VolatileIntPtr { 105 operator int volatile *(); 106 }; 107 108 struct ConstIntPtr { 109 operator int const *(); 110 }; 111 112 struct VolatileIntPtrRef { 113 operator int volatile *&(); 114 }; 115 116 struct ConstIntPtrRef { 117 operator int const *&(); 118 }; 119 120 void 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 150 void test_assign_restrictions(ShortRef& sr) { 151 sr = (short)0; // expected-error{{no viable overloaded '='}} 152 } 153 154 struct Base { }; 155 struct Derived1 : Base { }; 156 struct Derived2 : Base { }; 157 158 template<typename T> 159 struct ConvertibleToPtrOf { 160 operator T*(); 161 }; 162 163 bool test_with_base_ptrs(ConvertibleToPtrOf<Derived1> d1, 164 ConvertibleToPtrOf<Derived2> d2) { 165 return d1 == d2; // expected-error{{invalid operands}} 166 } 167 168 // DR425 169 struct A { 170 template< typename T > operator T() const; 171 }; 172 173 void 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 77 candidates omitted; pass -fshow-overloads=all to show them}} 178 } 179 180 // pr5432 181 enum e {X}; 182 183 const int a[][2] = {{1}}; 184 185 int test_pr5432() { 186 return a[X][X]; 187 } 188 189 void f() { 190 (void)__extension__(A()); 191 } 192 193 namespace 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 204 namespace 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 224 namespace 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