overloaded-operator.cpp revision e63ef48b76b84e7ffb0a38fbf475ddea5c48adb4
1// RUN: clang -fsyntax-only -verify %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; candidates are:}} 28} 29 30struct A { 31 bool operator==(Z&); // expected-note{{candidate function}} 32}; 33 34A make_A(); 35 36bool operator==(A&, Z&); // expected-note{{candidate function}} 37 38void h(A a, const A ac, Z z) { 39 make_A() == z; 40 a == z; // expected-error{{use of overloaded operator '==' is ambiguous; candidates are:}} 41 ac == z; // expected-error{{invalid operands to binary expression ('struct A const' and 'struct Z')}} 42} 43 44struct B { 45 bool operator==(const B&) const; 46 47 void test(Z z) { 48 make_A() == z; 49 } 50}; 51 52enum Enum1 { }; 53enum Enum2 { }; 54 55struct E1 { 56 E1(Enum1) { } 57}; 58 59struct E2 { 60 E2(Enum2); 61}; 62 63// C++ [over.match.oper]p3 - enum restriction. 64float& operator==(E1, E2); 65 66void enum_test(Enum1 enum1, Enum2 enum2, E1 e1, E2 e2) { 67 float &f1 = (e1 == e2); 68 float &f2 = (enum1 == e2); 69 float &f3 = (e1 == enum2); 70 float &f4 = (enum1 == enum2); // expected-error{{non-const reference to type 'float' cannot be initialized with a temporary of type '_Bool'}} 71} 72 73 74struct PostInc { 75 PostInc operator++(int); 76 PostInc& operator++(); 77}; 78 79struct PostDec { 80 PostDec operator--(int); 81 PostDec& operator--(); 82}; 83 84void incdec_test(PostInc pi, PostDec pd) { 85 const PostInc& pi1 = pi++; 86 const PostDec& pd1 = pd--; 87 PostInc &pi2 = ++pi; 88 PostDec &pd2 = --pd; 89} 90 91struct SmartPtr { 92 int& operator*(); 93 long& operator*() const volatile; 94}; 95 96void test_smartptr(SmartPtr ptr, const SmartPtr cptr, 97 const volatile SmartPtr cvptr) { 98 int &ir = *ptr; 99 long &lr = *cptr; 100 long &lr2 = *cvptr; 101} 102 103 104struct ArrayLike { 105 int& operator[](int); 106}; 107 108void test_arraylike(ArrayLike a) { 109 int& ir = a[17]; 110} 111 112struct SmartRef { 113 int* operator&(); 114}; 115 116void test_smartref(SmartRef r) { 117 int* ip = &r; 118} 119 120bool& operator,(X, Y); 121 122void test_comma(X x, Y y) { 123 bool& b1 = (x, y); 124 X& xr = (x, x); 125} 126 127 128struct Callable { 129 int& operator()(int, double = 2.71828); // expected-note{{candidate function}} 130 float& operator()(int, double, long, ...); // expected-note{{candidate function}} 131}; 132 133void test_callable(Callable c) { 134 int &ir = c(1); 135 float &fr = c(1, 3.14159, 17, 42); 136 137 c(); // expected-error{{no matching function for call to object of type 'struct Callable'; candidates are:}} 138} 139 140typedef float FLOAT; 141typedef int& INTREF; 142typedef INTREF Func1(FLOAT, double); 143typedef float& Func2(int, double); 144 145struct ConvertToFunc { 146 operator Func1*(); // expected-note{{conversion candidate of type 'INTREF (*)(FLOAT, double)'}} 147 operator Func2&(); // expected-note{{conversion candidate of type 'float &(&)(int, double)'}} 148 void operator()(); 149}; 150 151void test_funcptr_call(ConvertToFunc ctf) { 152 int &i1 = ctf(1.0f, 2.0); 153 float &f2 = ctf((short int)1, 1.0f); 154 ctf((long int)17, 2.0); // expected-error{{error: call to object of type 'struct ConvertToFunc' is ambiguous; candidates are:}} 155 ctf(); 156} 157 158struct HasMember { 159 int m; 160}; 161 162struct Arrow1 { 163 HasMember* operator->(); 164}; 165 166struct Arrow2 { 167 Arrow1 operator->(); // expected-note{{candidate function}} 168}; 169 170void test_arrow(Arrow1 a1, Arrow2 a2, const Arrow2 a3) { 171 int &i1 = a1->m; 172 int &i2 = a2->m; 173 a3->m; // expected-error{{no viable overloaded 'operator->'; candidate is}} 174} 175 176struct CopyConBase { 177}; 178 179struct CopyCon : public CopyConBase { 180 CopyCon(const CopyConBase &Base); 181 182 CopyCon(const CopyConBase *Base) { 183 *this = *Base; 184 } 185}; 186