1 // RUN: %clang_cc1 -fsyntax-only -verify %s 2 class X { }; 3 4 X operator+(X, X); 5 6 void f(X x) { 7 x = x + x; 8 } 9 10 struct Y; 11 struct Z; 12 13 struct Y { 14 Y(const Z&); 15 }; 16 17 struct Z { 18 Z(const Y&); 19 }; 20 21 Y operator+(Y, Y); 22 bool operator-(Y, Y); // expected-note{{candidate function}} 23 bool operator-(Z, Z); // expected-note{{candidate function}} 24 25 void g(Y y, Z z) { 26 y = y + z; 27 bool b = y - z; // expected-error{{use of overloaded operator '-' is ambiguous}} 28 } 29 30 struct A { 31 bool operator==(Z&); // expected-note 2{{candidate function}} 32 }; 33 34 A make_A(); 35 36 bool operator==(A&, Z&); // expected-note 3{{candidate function}} 37 38 void h(A a, const A ac, Z z) { 39 make_A() == z; // expected-warning{{equality comparison result unused}} 40 a == z; // expected-error{{use of overloaded operator '==' is ambiguous}} 41 ac == z; // expected-error{{invalid operands to binary expression ('const A' and 'Z')}} 42 } 43 44 struct B { 45 bool operator==(const B&) const; 46 47 void test(Z z) { 48 make_A() == z; // expected-warning{{equality comparison result unused}} 49 } 50 }; 51 52 // we shouldn't see warnings about self-comparison, 53 // this is a member function, we dunno what it'll do 54 bool i(B b) 55 { 56 return b == b; 57 } 58 59 enum Enum1 { }; 60 enum Enum2 { }; 61 62 struct E1 { 63 E1(Enum1) { } 64 }; 65 66 struct E2 { 67 E2(Enum2); 68 }; 69 70 // C++ [over.match.oper]p3 - enum restriction. 71 float& operator==(E1, E2); // expected-note{{candidate function}} 72 73 void enum_test(Enum1 enum1, Enum2 enum2, E1 e1, E2 e2, Enum1 next_enum1) { 74 float &f1 = (e1 == e2); 75 float &f2 = (enum1 == e2); 76 float &f3 = (e1 == enum2); 77 float &f4 = (enum1 == next_enum1); // expected-error{{non-const lvalue reference to type 'float' cannot bind to a temporary of type 'bool'}} 78 } 79 80 // PR5244 - Argument-dependent lookup would include the two operators below, 81 // which would break later assumptions and lead to a crash. 82 class pr5244_foo 83 { 84 pr5244_foo(int); 85 pr5244_foo(char); 86 }; 87 88 bool operator==(const pr5244_foo& s1, const pr5244_foo& s2); // expected-note{{candidate function}} 89 bool operator==(char c, const pr5244_foo& s); // expected-note{{candidate function}} 90 91 enum pr5244_bar 92 { 93 pr5244_BAR 94 }; 95 96 class pr5244_baz 97 { 98 public: 99 pr5244_bar quux; 100 }; 101 102 void pr5244_barbaz() 103 { 104 pr5244_baz quuux; 105 (void)(pr5244_BAR == quuux.quux); 106 } 107 108 109 110 struct PostInc { 111 PostInc operator++(int); 112 PostInc& operator++(); 113 }; 114 115 struct PostDec { 116 PostDec operator--(int); 117 PostDec& operator--(); 118 }; 119 120 void incdec_test(PostInc pi, PostDec pd) { 121 const PostInc& pi1 = pi++; 122 const PostDec& pd1 = pd--; 123 PostInc &pi2 = ++pi; 124 PostDec &pd2 = --pd; 125 } 126 127 struct SmartPtr { 128 int& operator*(); 129 long& operator*() const volatile; 130 }; 131 132 void test_smartptr(SmartPtr ptr, const SmartPtr cptr, 133 const volatile SmartPtr cvptr) { 134 int &ir = *ptr; 135 long &lr = *cptr; 136 long &lr2 = *cvptr; 137 } 138 139 140 struct ArrayLike { 141 int& operator[](int); 142 }; 143 144 void test_arraylike(ArrayLike a) { 145 int& ir = a[17]; 146 } 147 148 struct SmartRef { 149 int* operator&(); 150 }; 151 152 void test_smartref(SmartRef r) { 153 int* ip = &r; 154 } 155 156 bool& operator,(X, Y); 157 158 void test_comma(X x, Y y) { 159 bool& b1 = (x, y); 160 X& xr = (x, x); // expected-warning {{expression result unused}} 161 } 162 163 struct Callable { 164 int& operator()(int, double = 2.71828); // expected-note{{candidate function}} 165 float& operator()(int, double, long, ...); // expected-note{{candidate function}} 166 167 double& operator()(float); // expected-note{{candidate function}} 168 }; 169 170 struct Callable2 { 171 int& operator()(int i = 0); 172 double& operator()(...) const; 173 }; 174 175 struct DerivesCallable : public Callable { 176 }; 177 178 void test_callable(Callable c, Callable2 c2, const Callable2& c2c, 179 DerivesCallable dc) { 180 int &ir = c(1); 181 float &fr = c(1, 3.14159, 17, 42); 182 183 c(); // expected-error{{no matching function for call to object of type 'Callable'}} 184 185 double &dr = c(1.0f); 186 187 int &ir2 = c2(); 188 int &ir3 = c2(1); 189 double &fr2 = c2c(); 190 191 int &ir4 = dc(17); 192 double &fr3 = dc(3.14159f); 193 } 194 195 typedef float FLOAT; 196 typedef int& INTREF; 197 typedef INTREF Func1(FLOAT, double); 198 typedef float& Func2(int, double); 199 200 struct ConvertToFunc { 201 operator Func1*(); // expected-note 2{{conversion candidate of type 'INTREF (*)(FLOAT, double)'}} 202 operator Func2&(); // expected-note 2{{conversion candidate of type 'float &(&)(int, double)'}} 203 void operator()(); 204 }; 205 206 struct ConvertToFuncDerived : ConvertToFunc { }; 207 208 void test_funcptr_call(ConvertToFunc ctf, ConvertToFuncDerived ctfd) { 209 int &i1 = ctf(1.0f, 2.0); 210 float &f1 = ctf((short int)1, 1.0f); 211 ctf((long int)17, 2.0); // expected-error{{call to object of type 'ConvertToFunc' is ambiguous}} 212 ctf(); 213 214 int &i2 = ctfd(1.0f, 2.0); 215 float &f2 = ctfd((short int)1, 1.0f); 216 ctfd((long int)17, 2.0); // expected-error{{call to object of type 'ConvertToFuncDerived' is ambiguous}} 217 ctfd(); 218 } 219 220 struct HasMember { 221 int m; 222 }; 223 224 struct Arrow1 { 225 HasMember* operator->(); 226 }; 227 228 struct Arrow2 { 229 Arrow1 operator->(); // expected-note{{candidate function}} 230 }; 231 232 void test_arrow(Arrow1 a1, Arrow2 a2, const Arrow2 a3) { 233 int &i1 = a1->m; 234 int &i2 = a2->m; 235 a3->m; // expected-error{{no viable overloaded 'operator->'; candidate is}} 236 } 237 238 struct CopyConBase { 239 }; 240 241 struct CopyCon : public CopyConBase { 242 CopyCon(const CopyConBase &Base); 243 244 CopyCon(const CopyConBase *Base) { 245 *this = *Base; 246 } 247 }; 248 249 namespace N { 250 struct X { }; 251 } 252 253 namespace M { 254 N::X operator+(N::X, N::X); 255 } 256 257 namespace M { 258 void test_X(N::X x) { 259 (void)(x + x); 260 } 261 } 262 263 struct AA { bool operator!=(AA&); }; 264 struct BB : AA {}; 265 bool x(BB y, BB z) { return y != z; } 266 267 268 struct AX { 269 AX& operator ->(); // expected-note {{declared here}} 270 int b; 271 }; 272 273 void m() { 274 AX a; 275 a->b = 0; // expected-error {{circular pointer delegation detected}} 276 } 277 278 struct CircA { 279 struct CircB& operator->(); // expected-note {{declared here}} 280 int val; 281 }; 282 struct CircB { 283 struct CircC& operator->(); // expected-note {{declared here}} 284 }; 285 struct CircC { 286 struct CircA& operator->(); // expected-note {{declared here}} 287 }; 288 289 void circ() { 290 CircA a; 291 a->val = 0; // expected-error {{circular pointer delegation detected}} 292 } 293 294 // PR5360: Arrays should lead to built-in candidates for subscript. 295 typedef enum { 296 LastReg = 23, 297 } Register; 298 class RegAlloc { 299 int getPriority(Register r) { 300 return usepri[r]; 301 } 302 int usepri[LastReg + 1]; 303 }; 304 305 // PR5546: Don't generate incorrect and ambiguous overloads for multi-level 306 // arrays. 307 namespace pr5546 308 { 309 enum { X }; 310 extern const char *const sMoveCommands[][2][2]; 311 const char* a() { return sMoveCommands[X][0][0]; } 312 const char* b() { return (*(sMoveCommands+X))[0][0]; } 313 } 314 315 // PR5512 and its discussion 316 namespace pr5512 { 317 struct Y { 318 operator short(); 319 operator float(); 320 }; 321 void g_test(Y y) { 322 short s = 0; 323 // DR507, this should be ambiguous, but we special-case assignment 324 s = y; 325 // Note: DR507, this is ambiguous as specified 326 //s += y; 327 } 328 329 struct S {}; 330 void operator +=(int&, S); 331 void f(S s) { 332 int i = 0; 333 i += s; 334 } 335 336 struct A {operator int();}; 337 int a; 338 void b(A x) { 339 a += x; 340 } 341 } 342 343 // PR5900 344 namespace pr5900 { 345 struct NotAnArray {}; 346 void test0() { 347 NotAnArray x; 348 x[0] = 0; // expected-error {{does not provide a subscript operator}} 349 } 350 351 struct NonConstArray { 352 int operator[](unsigned); // expected-note {{candidate}} 353 }; 354 int test1() { 355 const NonConstArray x = NonConstArray(); 356 return x[0]; // expected-error {{no viable overloaded operator[] for type}} 357 } 358 359 // Not really part of this PR, but implemented at the same time. 360 struct NotAFunction {}; 361 void test2() { 362 NotAFunction x; 363 x(); // expected-error {{does not provide a call operator}} 364 } 365 } 366 367 // Operator lookup through using declarations. 368 namespace N { 369 struct X2 { }; 370 } 371 372 namespace N2 { 373 namespace M { 374 namespace Inner { 375 template<typename T> 376 N::X2 &operator<<(N::X2&, const T&); 377 } 378 using Inner::operator<<; 379 } 380 } 381 382 void test_lookup_through_using() { 383 using namespace N2::M; 384 N::X2 x; 385 x << 17; 386 } 387 388 namespace rdar9136502 { 389 struct X { 390 int i(); 391 int i(int); 392 }; 393 394 struct Y { 395 Y &operator<<(int); 396 }; 397 398 void f(X x, Y y) { 399 y << x.i; // expected-error{{reference to non-static member function must be called}} 400 } 401 } 402 403 namespace rdar9222009 { 404 class StringRef { 405 inline bool operator==(StringRef LHS, StringRef RHS) { // expected-error{{overloaded 'operator==' must be a binary operator (has 3 parameters)}} 406 return !(LHS == RHS); // expected-error{{invalid operands to binary expression ('rdar9222009::StringRef' and 'rdar9222009::StringRef')}} 407 } 408 }; 409 410 } 411