1// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
2class X { };
3
4X operator+(X, X);
5
6void f(X x) {
7  x = x + x;
8}
9
10struct Y;
11struct Z;
12
13struct Y {
14  Y(const Z&);
15};
16
17struct Z {
18  Z(const Y&);
19};
20
21Y operator+(Y, Y);
22bool operator-(Y, Y); // expected-note{{candidate function}}
23bool operator-(Z, Z); // expected-note{{candidate function}}
24
25void g(Y y, Z z) {
26  y = y + z;
27  bool b = y - z; // expected-error{{use of overloaded operator '-' is ambiguous}}
28}
29
30struct A {
31  bool operator==(Z&); // expected-note 2{{candidate function}}
32};
33
34A make_A();
35
36bool operator==(A&, Z&); // expected-note 3{{candidate function}}
37
38void 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
44struct 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
54bool i(B b)
55{
56  return b == b;
57}
58
59enum Enum1 { };
60enum Enum2 { };
61
62struct E1 {
63  E1(Enum1) { }
64};
65
66struct E2 {
67  E2(Enum2);
68};
69
70// C++ [over.match.oper]p3 - enum restriction.
71float& operator==(E1, E2);  // expected-note{{candidate function}}
72
73void 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.
82class pr5244_foo
83{
84  pr5244_foo(int);
85  pr5244_foo(char);
86};
87
88bool operator==(const pr5244_foo& s1, const pr5244_foo& s2); // expected-note{{candidate function}}
89bool operator==(char c, const pr5244_foo& s); // expected-note{{candidate function}}
90
91enum pr5244_bar
92{
93    pr5244_BAR
94};
95
96class pr5244_baz
97{
98public:
99    pr5244_bar quux;
100};
101
102void pr5244_barbaz()
103{
104  pr5244_baz quuux;
105  (void)(pr5244_BAR == quuux.quux);
106}
107
108
109
110struct PostInc {
111  PostInc operator++(int);
112  PostInc& operator++();
113};
114
115struct PostDec {
116  PostDec operator--(int);
117  PostDec& operator--();
118};
119
120void 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
127struct SmartPtr {
128  int& operator*();
129  long& operator*() const volatile;
130};
131
132void 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
140struct ArrayLike {
141  int& operator[](int);
142};
143
144void test_arraylike(ArrayLike a) {
145  int& ir = a[17];
146}
147
148struct SmartRef {
149  int* operator&();
150};
151
152void test_smartref(SmartRef r) {
153  int* ip = &r;
154}
155
156bool& operator,(X, Y);
157
158void test_comma(X x, Y y) {
159  bool& b1 = (x, y);
160  X& xr = (x, x); // expected-warning {{expression result unused}}
161}
162
163struct 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
170struct Callable2 {
171  int& operator()(int i = 0);
172  double& operator()(...) const;
173};
174
175struct DerivesCallable : public Callable {
176};
177
178void 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
195typedef float FLOAT;
196typedef int& INTREF;
197typedef INTREF Func1(FLOAT, double);
198typedef float& Func2(int, double);
199
200struct 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
206struct ConvertToFuncDerived : ConvertToFunc { };
207
208void 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
220struct HasMember {
221  int m;
222};
223
224struct Arrow1 {
225  HasMember* operator->();
226};
227
228struct Arrow2 {
229  Arrow1 operator->(); // expected-note{{candidate function}}
230};
231
232void 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
238struct CopyConBase {
239};
240
241struct CopyCon : public CopyConBase {
242  CopyCon(const CopyConBase &Base);
243
244  CopyCon(const CopyConBase *Base) {
245    *this = *Base;
246  }
247};
248
249namespace N {
250  struct X { };
251}
252
253namespace M {
254  N::X operator+(N::X, N::X);
255}
256
257namespace M {
258  void test_X(N::X x) {
259    (void)(x + x);
260  }
261}
262
263struct AA { bool operator!=(AA&); };
264struct BB : AA {};
265bool x(BB y, BB z) { return y != z; }
266
267
268struct AX {
269  AX& operator ->();	 // expected-note {{declared here}}
270  int b;
271};
272
273void m() {
274  AX a;
275  a->b = 0; // expected-error {{circular pointer delegation detected}}
276}
277
278struct CircA {
279  struct CircB& operator->(); // expected-note {{declared here}}
280  int val;
281};
282struct CircB {
283  struct CircC& operator->(); // expected-note {{declared here}}
284};
285struct CircC {
286  struct CircA& operator->(); // expected-note {{declared here}}
287};
288
289void 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.
295typedef enum {
296  LastReg = 23,
297} Register;
298class 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.
307namespace 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
316namespace 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
344namespace 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.
368namespace N {
369  struct X2 { };
370}
371
372namespace 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
382void test_lookup_through_using() {
383  using namespace N2::M;
384  N::X2 x;
385  x << 17;
386}
387
388namespace 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
404namespace rdar9222009 {
405class 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
413namespace PR11784 {
414  struct A { A& operator=(void (*x)()); };
415  void f();
416  void f(int);
417  void g() { A x; x = f; }
418}
419
420namespace 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
445struct InvalidOperatorEquals {
446  InvalidOperatorEquals operator=() = delete; // expected-error {{overloaded 'operator=' must be a binary operator}}
447};
448
449namespace 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
456namespace 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
510namespace 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