overloaded-operator.cpp revision 644be853b87cae94fcabaf309a5e482a8c291fb9
1// RUN: clang-cc -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 2{{candidate function}} 32}; 33 34A make_A(); 35 36bool operator==(A&, Z&); // expected-note 2{{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 lvalue reference to type 'float' cannot be initialized with a temporary of type 'bool'}} 71} 72 73// PR5244 - Argument-dependent lookup would include the two operators below, 74// which would break later assumptions and lead to a crash. 75class pr5244_foo 76{ 77 pr5244_foo(int); 78 pr5244_foo(char); 79}; 80 81bool operator==(const pr5244_foo& s1, const pr5244_foo& s2); 82bool operator==(char c, const pr5244_foo& s); 83 84enum pr5244_bar 85{ 86 pr5244_BAR 87}; 88 89class pr5244_baz 90{ 91 pr5244_bar quux; 92}; 93 94void pr5244_barbaz() 95{ 96 pr5244_baz quuux; 97 (void)(pr5244_BAR == quuux.quux); 98} 99 100 101 102struct PostInc { 103 PostInc operator++(int); 104 PostInc& operator++(); 105}; 106 107struct PostDec { 108 PostDec operator--(int); 109 PostDec& operator--(); 110}; 111 112void incdec_test(PostInc pi, PostDec pd) { 113 const PostInc& pi1 = pi++; 114 const PostDec& pd1 = pd--; 115 PostInc &pi2 = ++pi; 116 PostDec &pd2 = --pd; 117} 118 119struct SmartPtr { 120 int& operator*(); 121 long& operator*() const volatile; 122}; 123 124void test_smartptr(SmartPtr ptr, const SmartPtr cptr, 125 const volatile SmartPtr cvptr) { 126 int &ir = *ptr; 127 long &lr = *cptr; 128 long &lr2 = *cvptr; 129} 130 131 132struct ArrayLike { 133 int& operator[](int); 134}; 135 136void test_arraylike(ArrayLike a) { 137 int& ir = a[17]; 138} 139 140struct SmartRef { 141 int* operator&(); 142}; 143 144void test_smartref(SmartRef r) { 145 int* ip = &r; 146} 147 148bool& operator,(X, Y); 149 150void test_comma(X x, Y y) { 151 bool& b1 = (x, y); 152 X& xr = (x, x); 153} 154 155struct Callable { 156 int& operator()(int, double = 2.71828); // expected-note{{candidate function}} 157 float& operator()(int, double, long, ...); // expected-note{{candidate function}} 158 159 double& operator()(float); // expected-note{{candidate function}} 160}; 161 162struct Callable2 { 163 int& operator()(int i = 0); 164 double& operator()(...) const; 165}; 166 167void test_callable(Callable c, Callable2 c2, const Callable2& c2c) { 168 int &ir = c(1); 169 float &fr = c(1, 3.14159, 17, 42); 170 171 c(); // expected-error{{no matching function for call to object of type 'struct Callable'; candidates are:}} 172 173 double &dr = c(1.0f); 174 175 int &ir2 = c2(); 176 int &ir3 = c2(1); 177 double &fr2 = c2c(); 178} 179 180typedef float FLOAT; 181typedef int& INTREF; 182typedef INTREF Func1(FLOAT, double); 183typedef float& Func2(int, double); 184 185struct ConvertToFunc { 186 operator Func1*(); // expected-note{{conversion candidate of type 'INTREF (*)(FLOAT, double)'}} 187 operator Func2&(); // expected-note{{conversion candidate of type 'float &(&)(int, double)'}} 188 void operator()(); 189}; 190 191void test_funcptr_call(ConvertToFunc ctf) { 192 int &i1 = ctf(1.0f, 2.0); 193 float &f2 = ctf((short int)1, 1.0f); 194 ctf((long int)17, 2.0); // expected-error{{error: call to object of type 'struct ConvertToFunc' is ambiguous; candidates are:}} 195 ctf(); 196} 197 198struct HasMember { 199 int m; 200}; 201 202struct Arrow1 { 203 HasMember* operator->(); 204}; 205 206struct Arrow2 { 207 Arrow1 operator->(); // expected-note{{candidate function}} 208}; 209 210void test_arrow(Arrow1 a1, Arrow2 a2, const Arrow2 a3) { 211 int &i1 = a1->m; 212 int &i2 = a2->m; 213 a3->m; // expected-error{{no viable overloaded 'operator->'; candidate is}} 214} 215 216struct CopyConBase { 217}; 218 219struct CopyCon : public CopyConBase { 220 CopyCon(const CopyConBase &Base); 221 222 CopyCon(const CopyConBase *Base) { 223 *this = *Base; 224 } 225}; 226 227namespace N { 228 struct X { }; 229} 230 231namespace M { 232 N::X operator+(N::X, N::X); 233} 234 235namespace M { 236 void test_X(N::X x) { 237 (void)(x + x); 238 } 239} 240 241struct AA { bool operator!=(AA&); }; 242struct BB : AA {}; 243bool x(BB y, BB z) { return y != z; } 244 245 246struct AX { 247 AX& operator ->(); // expected-note {{declared at}} 248 int b; 249}; 250 251void m() { 252 AX a; 253 a->b = 0; // expected-error {{circular pointer delegation detected}} 254} 255 256struct CircA { 257 struct CircB& operator->(); // expected-note {{declared at}} 258 int val; 259}; 260struct CircB { 261 struct CircC& operator->(); // expected-note {{declared at}} 262}; 263struct CircC { 264 struct CircA& operator->(); // expected-note {{declared at}} 265}; 266 267void circ() { 268 CircA a; 269 a->val = 0; // expected-error {{circular pointer delegation detected}} 270} 271