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