overloaded-operator.cpp revision f680a0fe2dcab32b59fe6fdf71145b5313c40950
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*(); 931ca50c3f541dd637063b9d186a7ea193e3440a48Douglas Gregor long& operator*() const volatile; 9474253736184c0717a0649922551bf9d8b6815651Douglas Gregor}; 9574253736184c0717a0649922551bf9d8b6815651Douglas Gregor 961ca50c3f541dd637063b9d186a7ea193e3440a48Douglas Gregorvoid test_smartptr(SmartPtr ptr, const SmartPtr cptr, 971ca50c3f541dd637063b9d186a7ea193e3440a48Douglas Gregor const volatile SmartPtr cvptr) { 9874253736184c0717a0649922551bf9d8b6815651Douglas Gregor int &ir = *ptr; 991ca50c3f541dd637063b9d186a7ea193e3440a48Douglas Gregor long &lr = *cptr; 1001ca50c3f541dd637063b9d186a7ea193e3440a48Douglas Gregor long &lr2 = *cvptr; 10174253736184c0717a0649922551bf9d8b6815651Douglas Gregor} 102337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor 103337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor 104337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregorstruct ArrayLike { 105337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor int& operator[](int); 106337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor}; 107337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor 108337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregorvoid test_arraylike(ArrayLike a) { 109337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor int& ir = a[17]; 110337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor} 111337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor 112337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregorstruct SmartRef { 113337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor int* operator&(); 114337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor}; 115337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor 116337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregorvoid test_smartref(SmartRef r) { 117337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor int* ip = &r; 118337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor} 119337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor 120337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregorbool& operator,(X, Y); 121337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor 122337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregorvoid test_comma(X x, Y y) { 123337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor bool& b1 = (x, y); 124337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor X& xr = (x, x); 125337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor} 126f9eb905197e44ed5634205512074993f6f40470dDouglas Gregor 127f9eb905197e44ed5634205512074993f6f40470dDouglas Gregorstruct Callable { 128f9eb905197e44ed5634205512074993f6f40470dDouglas Gregor int& operator()(int, double = 2.71828); // expected-note{{candidate function}} 129f9eb905197e44ed5634205512074993f6f40470dDouglas Gregor float& operator()(int, double, long, ...); // expected-note{{candidate function}} 130518fda1d121dcba3ad7276f5e9a94f733f6e5ecdDouglas Gregor 131518fda1d121dcba3ad7276f5e9a94f733f6e5ecdDouglas Gregor double& operator()(float); // expected-note{{candidate function}} 132518fda1d121dcba3ad7276f5e9a94f733f6e5ecdDouglas Gregor}; 133518fda1d121dcba3ad7276f5e9a94f733f6e5ecdDouglas Gregor 134518fda1d121dcba3ad7276f5e9a94f733f6e5ecdDouglas Gregorstruct Callable2 { 135518fda1d121dcba3ad7276f5e9a94f733f6e5ecdDouglas Gregor int& operator()(int i = 0); 136518fda1d121dcba3ad7276f5e9a94f733f6e5ecdDouglas Gregor double& operator()(...) const; 137f9eb905197e44ed5634205512074993f6f40470dDouglas Gregor}; 138f9eb905197e44ed5634205512074993f6f40470dDouglas Gregor 139518fda1d121dcba3ad7276f5e9a94f733f6e5ecdDouglas Gregorvoid test_callable(Callable c, Callable2 c2, const Callable2& c2c) { 140f9eb905197e44ed5634205512074993f6f40470dDouglas Gregor int &ir = c(1); 141f9eb905197e44ed5634205512074993f6f40470dDouglas Gregor float &fr = c(1, 3.14159, 17, 42); 142f9eb905197e44ed5634205512074993f6f40470dDouglas Gregor 143f9eb905197e44ed5634205512074993f6f40470dDouglas Gregor c(); // expected-error{{no matching function for call to object of type 'struct Callable'; candidates are:}} 144518fda1d121dcba3ad7276f5e9a94f733f6e5ecdDouglas Gregor 145518fda1d121dcba3ad7276f5e9a94f733f6e5ecdDouglas Gregor double &dr = c(1.0f); 146518fda1d121dcba3ad7276f5e9a94f733f6e5ecdDouglas Gregor 147518fda1d121dcba3ad7276f5e9a94f733f6e5ecdDouglas Gregor int &ir2 = c2(); 148518fda1d121dcba3ad7276f5e9a94f733f6e5ecdDouglas Gregor int &ir3 = c2(1); 149518fda1d121dcba3ad7276f5e9a94f733f6e5ecdDouglas Gregor double &fr2 = c2c(); 150f9eb905197e44ed5634205512074993f6f40470dDouglas Gregor} 151106c6eb3f1380bfe243a62d8f0f8bce6a7c8d5c6Douglas Gregor 152621b3933e570792810386b891264c78e3bd7b169Douglas Gregortypedef float FLOAT; 153621b3933e570792810386b891264c78e3bd7b169Douglas Gregortypedef int& INTREF; 154621b3933e570792810386b891264c78e3bd7b169Douglas Gregortypedef INTREF Func1(FLOAT, double); 155106c6eb3f1380bfe243a62d8f0f8bce6a7c8d5c6Douglas Gregortypedef float& Func2(int, double); 156106c6eb3f1380bfe243a62d8f0f8bce6a7c8d5c6Douglas Gregor 157106c6eb3f1380bfe243a62d8f0f8bce6a7c8d5c6Douglas Gregorstruct ConvertToFunc { 158621b3933e570792810386b891264c78e3bd7b169Douglas Gregor operator Func1*(); // expected-note{{conversion candidate of type 'INTREF (*)(FLOAT, double)'}} 159106c6eb3f1380bfe243a62d8f0f8bce6a7c8d5c6Douglas Gregor operator Func2&(); // expected-note{{conversion candidate of type 'float &(&)(int, double)'}} 1609ebae31a97f862771dc5f6bd4923dd97131fed71Douglas Gregor void operator()(); 161106c6eb3f1380bfe243a62d8f0f8bce6a7c8d5c6Douglas Gregor}; 162106c6eb3f1380bfe243a62d8f0f8bce6a7c8d5c6Douglas Gregor 163106c6eb3f1380bfe243a62d8f0f8bce6a7c8d5c6Douglas Gregorvoid test_funcptr_call(ConvertToFunc ctf) { 164106c6eb3f1380bfe243a62d8f0f8bce6a7c8d5c6Douglas Gregor int &i1 = ctf(1.0f, 2.0); 165106c6eb3f1380bfe243a62d8f0f8bce6a7c8d5c6Douglas Gregor float &f2 = ctf((short int)1, 1.0f); 166106c6eb3f1380bfe243a62d8f0f8bce6a7c8d5c6Douglas Gregor ctf((long int)17, 2.0); // expected-error{{error: call to object of type 'struct ConvertToFunc' is ambiguous; candidates are:}} 1679ebae31a97f862771dc5f6bd4923dd97131fed71Douglas Gregor ctf(); 168106c6eb3f1380bfe243a62d8f0f8bce6a7c8d5c6Douglas Gregor} 1698ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregor 1708ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregorstruct HasMember { 1718ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregor int m; 1728ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregor}; 1738ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregor 1748ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregorstruct Arrow1 { 1758ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregor HasMember* operator->(); 1768ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregor}; 1778ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregor 1788ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregorstruct Arrow2 { 1798ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregor Arrow1 operator->(); // expected-note{{candidate function}} 1808ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregor}; 1818ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregor 1828ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregorvoid test_arrow(Arrow1 a1, Arrow2 a2, const Arrow2 a3) { 1838ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregor int &i1 = a1->m; 1848ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregor int &i2 = a2->m; 185e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl a3->m; // expected-error{{no viable overloaded 'operator->'; candidate is}} 1868ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregor} 187e63ef48b76b84e7ffb0a38fbf475ddea5c48adb4Douglas Gregor 188e63ef48b76b84e7ffb0a38fbf475ddea5c48adb4Douglas Gregorstruct CopyConBase { 189e63ef48b76b84e7ffb0a38fbf475ddea5c48adb4Douglas Gregor}; 190e63ef48b76b84e7ffb0a38fbf475ddea5c48adb4Douglas Gregor 191e63ef48b76b84e7ffb0a38fbf475ddea5c48adb4Douglas Gregorstruct CopyCon : public CopyConBase { 192e63ef48b76b84e7ffb0a38fbf475ddea5c48adb4Douglas Gregor CopyCon(const CopyConBase &Base); 193e63ef48b76b84e7ffb0a38fbf475ddea5c48adb4Douglas Gregor 194e63ef48b76b84e7ffb0a38fbf475ddea5c48adb4Douglas Gregor CopyCon(const CopyConBase *Base) { 195e63ef48b76b84e7ffb0a38fbf475ddea5c48adb4Douglas Gregor *this = *Base; 196e63ef48b76b84e7ffb0a38fbf475ddea5c48adb4Douglas Gregor } 197e63ef48b76b84e7ffb0a38fbf475ddea5c48adb4Douglas Gregor}; 198fa047648b2a5502d7eef117adb4777eb9a63baa6Douglas Gregor 199fa047648b2a5502d7eef117adb4777eb9a63baa6Douglas Gregornamespace N { 200fa047648b2a5502d7eef117adb4777eb9a63baa6Douglas Gregor struct X { }; 201fa047648b2a5502d7eef117adb4777eb9a63baa6Douglas Gregor} 202fa047648b2a5502d7eef117adb4777eb9a63baa6Douglas Gregor 203fa047648b2a5502d7eef117adb4777eb9a63baa6Douglas Gregornamespace M { 204fa047648b2a5502d7eef117adb4777eb9a63baa6Douglas Gregor N::X operator+(N::X, N::X); 205fa047648b2a5502d7eef117adb4777eb9a63baa6Douglas Gregor} 206fa047648b2a5502d7eef117adb4777eb9a63baa6Douglas Gregor 207fa047648b2a5502d7eef117adb4777eb9a63baa6Douglas Gregornamespace M { 208fa047648b2a5502d7eef117adb4777eb9a63baa6Douglas Gregor void test_X(N::X x) { 209f680a0fe2dcab32b59fe6fdf71145b5313c40950Douglas Gregor (void)(x + x); 210fa047648b2a5502d7eef117adb4777eb9a63baa6Douglas Gregor } 211fa047648b2a5502d7eef117adb4777eb9a63baa6Douglas Gregor} 212