overloaded-operator.cpp revision 337c6b9f5d502dc1c5acea628bf7bf9e828efc0e
1eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas Gregor// RUN: clang -fsyntax-only -verify %s
2eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas Gregorclass X { };
3eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas Gregor
4eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas GregorX operator+(X, X);
5eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas Gregor
6eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas Gregorvoid f(X x) {
7eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas Gregor  x = x + x;
8eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas Gregor}
9eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas Gregor
10eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas Gregorstruct Y;
11eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas Gregorstruct Z;
12eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas Gregor
13eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas Gregorstruct Y {
14eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas Gregor  Y(const Z&);
15eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas Gregor};
16eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas Gregor
17eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas Gregorstruct Z {
18eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas Gregor  Z(const Y&);
19eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas Gregor};
20eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas Gregor
21eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas GregorY operator+(Y, Y);
22eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas Gregorbool operator-(Y, Y); // expected-note{{candidate function}}
23eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas Gregorbool operator-(Z, Z); // expected-note{{candidate function}}
24eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas Gregor
25eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas Gregorvoid g(Y y, Z z) {
26eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas Gregor  y = y + z;
27eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas Gregor  bool b = y - z; // expected-error{{use of overloaded operator '-' is ambiguous; candidates are:}}
28eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas Gregor}
29eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas Gregor
3096176b3575823ea996c6140380dd17d9240c9766Douglas Gregorstruct A {
3196176b3575823ea996c6140380dd17d9240c9766Douglas Gregor  bool operator==(Z&); // expected-note{{candidate function}}
3296176b3575823ea996c6140380dd17d9240c9766Douglas Gregor};
3396176b3575823ea996c6140380dd17d9240c9766Douglas Gregor
3496176b3575823ea996c6140380dd17d9240c9766Douglas GregorA make_A();
35eaebc75ef6ff21fbc9f25ab4175cba465e4e0e43Douglas Gregor
3696176b3575823ea996c6140380dd17d9240c9766Douglas Gregorbool operator==(A&, Z&); // expected-note{{candidate function}}
3796176b3575823ea996c6140380dd17d9240c9766Douglas Gregor
3896176b3575823ea996c6140380dd17d9240c9766Douglas Gregorvoid h(A a, const A ac, Z z) {
3996176b3575823ea996c6140380dd17d9240c9766Douglas Gregor  make_A() == z;
4096176b3575823ea996c6140380dd17d9240c9766Douglas Gregor  a == z; // expected-error{{use of overloaded operator '==' is ambiguous; candidates are:}}
4196176b3575823ea996c6140380dd17d9240c9766Douglas Gregor  ac == z; // expected-error{{invalid operands to binary expression ('struct A const' and 'struct Z')}}
4296176b3575823ea996c6140380dd17d9240c9766Douglas Gregor}
4396176b3575823ea996c6140380dd17d9240c9766Douglas Gregor
4496176b3575823ea996c6140380dd17d9240c9766Douglas Gregorstruct B {
4596176b3575823ea996c6140380dd17d9240c9766Douglas Gregor  bool operator==(const B&) const;
4696176b3575823ea996c6140380dd17d9240c9766Douglas Gregor
4796176b3575823ea996c6140380dd17d9240c9766Douglas Gregor  void test(Z z) {
4896176b3575823ea996c6140380dd17d9240c9766Douglas Gregor    make_A() == z;
4996176b3575823ea996c6140380dd17d9240c9766Douglas Gregor  }
5096176b3575823ea996c6140380dd17d9240c9766Douglas Gregor};
51447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregor
52447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregorenum Enum1 { };
53447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregorenum Enum2 { };
54447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregor
55447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregorstruct E1 {
56447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregor  E1(Enum1) { }
57447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregor};
58447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregor
59447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregorstruct E2 {
60447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregor  E2(Enum2);
61447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregor};
62447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregor
63447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregor// C++ [over.match.oper]p3 - enum restriction.
64447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregorfloat& operator==(E1, E2);
65447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregor
66447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregorvoid enum_test(Enum1 enum1, Enum2 enum2, E1 e1, E2 e2) {
67447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregor  float &f1 = (e1 == e2);
68447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregor  float &f2 = (enum1 == e2);
69447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregor  float &f3 = (e1 == enum2);
70447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregor  float &f4 = (enum1 == enum2);  // expected-error{{non-const reference to type 'float' cannot be initialized with a temporary of type '_Bool'}}
71447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregor}
7274253736184c0717a0649922551bf9d8b6815651Douglas Gregor
7374253736184c0717a0649922551bf9d8b6815651Douglas Gregor
7474253736184c0717a0649922551bf9d8b6815651Douglas Gregorstruct PostInc {
7574253736184c0717a0649922551bf9d8b6815651Douglas Gregor  PostInc operator++(int);
7674253736184c0717a0649922551bf9d8b6815651Douglas Gregor  PostInc& operator++();
7774253736184c0717a0649922551bf9d8b6815651Douglas Gregor};
7874253736184c0717a0649922551bf9d8b6815651Douglas Gregor
7974253736184c0717a0649922551bf9d8b6815651Douglas Gregorstruct PostDec {
8074253736184c0717a0649922551bf9d8b6815651Douglas Gregor  PostDec operator--(int);
8174253736184c0717a0649922551bf9d8b6815651Douglas Gregor  PostDec& operator--();
8274253736184c0717a0649922551bf9d8b6815651Douglas Gregor};
8374253736184c0717a0649922551bf9d8b6815651Douglas Gregor
8474253736184c0717a0649922551bf9d8b6815651Douglas Gregorvoid incdec_test(PostInc pi, PostDec pd) {
8574253736184c0717a0649922551bf9d8b6815651Douglas Gregor  const PostInc& pi1 = pi++;
8674253736184c0717a0649922551bf9d8b6815651Douglas Gregor  const PostDec& pd1 = pd--;
8774253736184c0717a0649922551bf9d8b6815651Douglas Gregor  PostInc &pi2 = ++pi;
8874253736184c0717a0649922551bf9d8b6815651Douglas Gregor  PostDec &pd2 = --pd;
8974253736184c0717a0649922551bf9d8b6815651Douglas Gregor}
9074253736184c0717a0649922551bf9d8b6815651Douglas Gregor
9174253736184c0717a0649922551bf9d8b6815651Douglas Gregorstruct SmartPtr {
9274253736184c0717a0649922551bf9d8b6815651Douglas Gregor  int& operator*();
9374253736184c0717a0649922551bf9d8b6815651Douglas Gregor  // FIXME: spurious error:  long& operator*() const;
9474253736184c0717a0649922551bf9d8b6815651Douglas Gregor};
9574253736184c0717a0649922551bf9d8b6815651Douglas Gregor
9674253736184c0717a0649922551bf9d8b6815651Douglas Gregorvoid test_smartptr(SmartPtr ptr, const SmartPtr cptr) {
9774253736184c0717a0649922551bf9d8b6815651Douglas Gregor  int &ir = *ptr;
9874253736184c0717a0649922551bf9d8b6815651Douglas Gregor  // FIXME: reinstate long &lr = *cptr;
9974253736184c0717a0649922551bf9d8b6815651Douglas Gregor}
100337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor
101337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor
102337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregorstruct ArrayLike {
103337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor  int& operator[](int);
104337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor};
105337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor
106337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregorvoid test_arraylike(ArrayLike a) {
107337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor  int& ir = a[17];
108337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor}
109337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor
110337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregorstruct SmartRef {
111337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor  int* operator&();
112337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor};
113337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor
114337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregorvoid test_smartref(SmartRef r) {
115337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor  int* ip = &r;
116337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor}
117337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor
118337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregorbool& operator,(X, Y);
119337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor
120337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregorvoid test_comma(X x, Y y) {
121337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor  bool& b1 = (x, y);
122337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor  X& xr = (x, x);
123337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor}
124