overloaded-operator.cpp revision e63ef48b76b84e7ffb0a38fbf475ddea5c48adb4
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 Gregor 128f9eb905197e44ed5634205512074993f6f40470dDouglas Gregorstruct Callable { 129f9eb905197e44ed5634205512074993f6f40470dDouglas Gregor int& operator()(int, double = 2.71828); // expected-note{{candidate function}} 130f9eb905197e44ed5634205512074993f6f40470dDouglas Gregor float& operator()(int, double, long, ...); // expected-note{{candidate function}} 131f9eb905197e44ed5634205512074993f6f40470dDouglas Gregor}; 132f9eb905197e44ed5634205512074993f6f40470dDouglas Gregor 133f9eb905197e44ed5634205512074993f6f40470dDouglas Gregorvoid test_callable(Callable c) { 134f9eb905197e44ed5634205512074993f6f40470dDouglas Gregor int &ir = c(1); 135f9eb905197e44ed5634205512074993f6f40470dDouglas Gregor float &fr = c(1, 3.14159, 17, 42); 136f9eb905197e44ed5634205512074993f6f40470dDouglas Gregor 137f9eb905197e44ed5634205512074993f6f40470dDouglas Gregor c(); // expected-error{{no matching function for call to object of type 'struct Callable'; candidates are:}} 138f9eb905197e44ed5634205512074993f6f40470dDouglas Gregor} 139106c6eb3f1380bfe243a62d8f0f8bce6a7c8d5c6Douglas Gregor 140621b3933e570792810386b891264c78e3bd7b169Douglas Gregortypedef float FLOAT; 141621b3933e570792810386b891264c78e3bd7b169Douglas Gregortypedef int& INTREF; 142621b3933e570792810386b891264c78e3bd7b169Douglas Gregortypedef INTREF Func1(FLOAT, double); 143106c6eb3f1380bfe243a62d8f0f8bce6a7c8d5c6Douglas Gregortypedef float& Func2(int, double); 144106c6eb3f1380bfe243a62d8f0f8bce6a7c8d5c6Douglas Gregor 145106c6eb3f1380bfe243a62d8f0f8bce6a7c8d5c6Douglas Gregorstruct ConvertToFunc { 146621b3933e570792810386b891264c78e3bd7b169Douglas Gregor operator Func1*(); // expected-note{{conversion candidate of type 'INTREF (*)(FLOAT, double)'}} 147106c6eb3f1380bfe243a62d8f0f8bce6a7c8d5c6Douglas Gregor operator Func2&(); // expected-note{{conversion candidate of type 'float &(&)(int, double)'}} 1489ebae31a97f862771dc5f6bd4923dd97131fed71Douglas Gregor void operator()(); 149106c6eb3f1380bfe243a62d8f0f8bce6a7c8d5c6Douglas Gregor}; 150106c6eb3f1380bfe243a62d8f0f8bce6a7c8d5c6Douglas Gregor 151106c6eb3f1380bfe243a62d8f0f8bce6a7c8d5c6Douglas Gregorvoid test_funcptr_call(ConvertToFunc ctf) { 152106c6eb3f1380bfe243a62d8f0f8bce6a7c8d5c6Douglas Gregor int &i1 = ctf(1.0f, 2.0); 153106c6eb3f1380bfe243a62d8f0f8bce6a7c8d5c6Douglas Gregor float &f2 = ctf((short int)1, 1.0f); 154106c6eb3f1380bfe243a62d8f0f8bce6a7c8d5c6Douglas Gregor ctf((long int)17, 2.0); // expected-error{{error: call to object of type 'struct ConvertToFunc' is ambiguous; candidates are:}} 1559ebae31a97f862771dc5f6bd4923dd97131fed71Douglas Gregor ctf(); 156106c6eb3f1380bfe243a62d8f0f8bce6a7c8d5c6Douglas Gregor} 1578ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregor 1588ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregorstruct HasMember { 1598ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregor int m; 1608ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregor}; 1618ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregor 1628ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregorstruct Arrow1 { 1638ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregor HasMember* operator->(); 1648ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregor}; 1658ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregor 1668ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregorstruct Arrow2 { 1678ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregor Arrow1 operator->(); // expected-note{{candidate function}} 1688ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregor}; 1698ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregor 1708ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregorvoid test_arrow(Arrow1 a1, Arrow2 a2, const Arrow2 a3) { 1718ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregor int &i1 = a1->m; 1728ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregor int &i2 = a2->m; 173e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl a3->m; // expected-error{{no viable overloaded 'operator->'; candidate is}} 1748ba10745f525467e91bbaec21044bf4d9017a988Douglas Gregor} 175e63ef48b76b84e7ffb0a38fbf475ddea5c48adb4Douglas Gregor 176e63ef48b76b84e7ffb0a38fbf475ddea5c48adb4Douglas Gregorstruct CopyConBase { 177e63ef48b76b84e7ffb0a38fbf475ddea5c48adb4Douglas Gregor}; 178e63ef48b76b84e7ffb0a38fbf475ddea5c48adb4Douglas Gregor 179e63ef48b76b84e7ffb0a38fbf475ddea5c48adb4Douglas Gregorstruct CopyCon : public CopyConBase { 180e63ef48b76b84e7ffb0a38fbf475ddea5c48adb4Douglas Gregor CopyCon(const CopyConBase &Base); 181e63ef48b76b84e7ffb0a38fbf475ddea5c48adb4Douglas Gregor 182e63ef48b76b84e7ffb0a38fbf475ddea5c48adb4Douglas Gregor CopyCon(const CopyConBase *Base) { 183e63ef48b76b84e7ffb0a38fbf475ddea5c48adb4Douglas Gregor *this = *Base; 184e63ef48b76b84e7ffb0a38fbf475ddea5c48adb4Douglas Gregor } 185e63ef48b76b84e7ffb0a38fbf475ddea5c48adb4Douglas Gregor}; 186