1 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %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->'}} |
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(); // expected-note{{possible target for call}} |
391 | int i(int); // expected-note{{possible target for call}} |
392 | }; |
393 | |
394 | struct Y { |
395 | Y &operator<<(int); |
396 | }; |
397 | |
398 | void f(X x, Y y) { |
399 | y << x |
400 | .i; // expected-error{{reference to non-static member function must be called; did you mean to call it with no arguments?}} |
401 | } |
402 | } |
403 | |
404 | namespace rdar9222009 { |
405 | class StringRef { |
406 | inline bool operator==(StringRef LHS, StringRef RHS) { // expected-error{{overloaded 'operator==' must be a binary operator (has 3 parameters)}} |
407 | return !(LHS == RHS); // expected-error{{invalid operands to binary expression ('rdar9222009::StringRef' and 'rdar9222009::StringRef')}} |
408 | } |
409 | }; |
410 | |
411 | } |
412 | |
413 | namespace PR11784 { |
414 | struct A { A& operator=(void (*x)()); }; |
415 | void f(); |
416 | void f(int); |
417 | void g() { A x; x = f; } |
418 | } |
419 | |
420 | namespace test10 { |
421 | struct A { |
422 | void operator[](float (*fn)(int)); // expected-note 2 {{not viable: no overload of 'bar' matching 'float (*)(int)'}} |
423 | }; |
424 | |
425 | float foo(int); |
426 | float foo(float); |
427 | |
428 | template <class T> T bar(T); |
429 | template <class T, class U> T bar(U); |
430 | |
431 | void test(A &a) { |
432 | a[&foo]; |
433 | a[foo]; |
434 | |
435 | a[&bar<int>]; // expected-error {{no viable overloaded operator[]}} |
436 | a[bar<int>]; // expected-error {{no viable overloaded operator[]}} |
437 | |
438 | // If these fail, it's because we're not letting the overload |
439 | // resolution for operator| resolve the overload of 'bar'. |
440 | a[&bar<float>]; |
441 | a[bar<float>]; |
442 | } |
443 | } |
444 | |
445 | struct InvalidOperatorEquals { |
446 | InvalidOperatorEquals operator=() = delete; // expected-error {{overloaded 'operator=' must be a binary operator}} |
447 | }; |
448 | |
449 | namespace PR7681 { |
450 | template <typename PT1, typename PT2> class PointerUnion; |
451 | void foo(PointerUnion<int*, float*> &Result) { |
452 | Result = 1; // expected-error {{no viable overloaded '='}} // expected-note {{type 'PointerUnion<int *, float *>' is incomplete}} |
453 | } |
454 | } |
455 | |
456 | namespace PR14995 { |
457 | struct B {}; |
458 | template<typename ...T> void operator++(B, T...) {} |
459 | |
460 | void f() { |
461 | B b; |
462 | b++; // ok |
463 | ++b; // ok |
464 | } |
465 | |
466 | template<typename... T> |
467 | struct C { |
468 | void operator-- (T...) {} |
469 | }; |
470 | |
471 | void g() { |
472 | C<int> postfix; |
473 | C<> prefix; |
474 | postfix--; // ok |
475 | --prefix; // ok |
476 | } |
477 | |
478 | struct D {}; |
479 | template<typename T> void operator++(D, T) {} |
480 | |
481 | void h() { |
482 | D d; |
483 | d++; // ok |
484 | ++d; // expected-error{{cannot increment value of type 'PR14995::D'}} |
485 | } |
486 | |
487 | template<typename...T> struct E { |
488 | void operator++(T...) {} // expected-error{{parameter of overloaded post-increment operator must have type 'int' (not 'char')}} |
489 | }; |
490 | |
491 | E<char> e; // expected-note {{in instantiation of template class 'PR14995::E<char>' requested here}} |
492 | |
493 | struct F { |
494 | template<typename... T> |
495 | int operator++ (T...) {} |
496 | }; |
497 | |
498 | int k1 = F().operator++(0, 0); |
499 | int k2 = F().operator++('0'); |
500 | // expected-error@-5 {{overloaded 'operator++' must be a unary or binary operator}} |
501 | // expected-note@-3 {{in instantiation of function template specialization 'PR14995::F::operator++<int, int>' requested here}} |
502 | // expected-error@-4 {{no matching member function for call to 'operator++'}} |
503 | // expected-note@-8 {{candidate template ignored: substitution failure}} |
504 | // expected-error@-9 {{parameter of overloaded post-increment operator must have type 'int' (not 'char')}} |
505 | // expected-note@-6 {{in instantiation of function template specialization 'PR14995::F::operator++<char>' requested here}} |
506 | // expected-error@-7 {{no matching member function for call to 'operator++'}} |
507 | // expected-note@-12 {{candidate template ignored: substitution failure}} |
508 | } // namespace PR14995 |
509 | |
510 | namespace ConversionVersusTemplateOrdering { |
511 | struct A { |
512 | operator short() = delete; |
513 | template <typename T> operator T(); |
514 | } a; |
515 | struct B { |
516 | template <typename T> operator T(); |
517 | operator short() = delete; |
518 | } b; |
519 | int x = a; |
520 | int y = b; |
521 | } |
522 | |
523 | namespace NoADLForMemberOnlyOperators { |
524 | template<typename T> struct A { typename T::error e; }; // expected-error {{type 'char' cannot be used prior to '::'}} |
525 | template<typename T> struct B { int n; }; |
526 | |
527 | void f(B<A<void> > b1, B<A<int> > b2, B<A<char> > b3) { |
528 | b1 = b1; // ok, does not instantiate A<void>. |
529 | (void)b1->n; // expected-error {{is not a pointer}} |
530 | b2[3]; // expected-error {{does not provide a subscript}} |
531 | b3 / 0; // expected-note {{in instantiation of}} expected-error {{invalid operands to}} |
532 | } |
533 | } |
534 | |
535 | |
536 | namespace PR27027 { |
537 | template <class T> void operator+(T, T) = delete; // expected-note 4 {{candidate}} |
538 | template <class T> void operator+(T) = delete; // expected-note 4 {{candidate}} |
539 | |
540 | struct A {} a_global; |
541 | void f() { |
542 | A a; |
543 | +a; // expected-error {{overload resolution selected deleted operator '+'}} |
544 | a + a; // expected-error {{overload resolution selected deleted operator '+'}} |
545 | bool operator+(A); |
546 | extern bool operator+(A, A); |
547 | +a; // OK |
548 | a + a; |
549 | } |
550 | bool test_global_1 = +a_global; // expected-error {{overload resolution selected deleted operator '+'}} |
551 | bool test_global_2 = a_global + a_global; // expected-error {{overload resolution selected deleted operator '+'}} |
552 | } |
553 | |
554 | namespace LateADLInNonDependentExpressions { |
555 | struct A {}; |
556 | struct B : A {}; |
557 | int &operator+(A, A); |
558 | int &operator!(A); |
559 | int &operator+=(A, A); |
560 | int &operator<<(A, A); |
561 | int &operator++(A); |
562 | int &operator++(A, int); |
563 | int &operator->*(A, A); |
564 | |
565 | template<typename T> void f() { |
566 | // An instantiation-dependent value of type B. |
567 | // These are all non-dependent operator calls of type int&. |
568 | #define idB ((void()), B()) |
569 | int &a = idB + idB, |
570 | &b = !idB, |
571 | &c = idB += idB, |
572 | &d = idB << idB, |
573 | &e = ++idB, |
574 | &f = idB++, |
575 | &g = idB ->* idB; |
576 | } |
577 | |
578 | // These should not be found by ADL in the template instantiation. |
579 | float &operator+(B, B); |
580 | float &operator!(B); |
581 | float &operator+=(B, B); |
582 | float &operator<<(B, B); |
583 | float &operator++(B); |
584 | float &operator++(B, int); |
585 | float &operator->*(B, B); |
586 | template void f<int>(); |
587 | } |
588 | |