From: Douglas Gregor Date: Thu, 5 May 2011 00:13:13 +0000 (+0000) Subject: With invalid overloaded operators, we can get into funny cases where X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=439d3c3d76f858df5f25239f2a70f04312eacb5b;p=clang With invalid overloaded operators, we can get into funny cases where the overloading of member and non-member functions results in arity mismatches that don't fit well into our overload-printing scheme. This only happens for invalid code (which breaks the arity invariants for these cases), so just suppress the diagnostic rather than inventing anything new. Fixes . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130902 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 3f3ed0e1f9..79caecc5a8 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -6676,6 +6676,15 @@ void DiagnoseArityMismatch(Sema &S, OverloadCandidate *Cand, unsigned MinParams = Fn->getMinRequiredArguments(); + // With invalid overloaded operators, it's possible that we think we + // have an arity mismatch when it fact it looks like we have the + // right number of arguments, because only overloaded operators have + // the weird behavior of overloading member and non-member functions. + // Just don't report anything. + if (Fn->isInvalidDecl() && + Fn->getDeclName().getNameKind() == DeclarationName::CXXOperatorName) + return; + // at least / at most / exactly unsigned mode, modeCount; if (NumFormalArgs < MinParams) { diff --git a/test/SemaCXX/overloaded-operator.cpp b/test/SemaCXX/overloaded-operator.cpp index 44d013fe79..462d0234f3 100644 --- a/test/SemaCXX/overloaded-operator.cpp +++ b/test/SemaCXX/overloaded-operator.cpp @@ -33,7 +33,7 @@ struct A { A make_A(); -bool operator==(A&, Z&); // expected-note 2{{candidate function}} +bool operator==(A&, Z&); // expected-note 3{{candidate function}} void h(A a, const A ac, Z z) { make_A() == z; @@ -68,7 +68,7 @@ struct E2 { }; // C++ [over.match.oper]p3 - enum restriction. -float& operator==(E1, E2); +float& operator==(E1, E2); // expected-note{{candidate function}} void enum_test(Enum1 enum1, Enum2 enum2, E1 e1, E2 e2, Enum1 next_enum1) { float &f1 = (e1 == e2); @@ -85,8 +85,8 @@ class pr5244_foo pr5244_foo(char); }; -bool operator==(const pr5244_foo& s1, const pr5244_foo& s2); -bool operator==(char c, const pr5244_foo& s); +bool operator==(const pr5244_foo& s1, const pr5244_foo& s2); // expected-note{{candidate function}} +bool operator==(char c, const pr5244_foo& s); // expected-note{{candidate function}} enum pr5244_bar { @@ -399,3 +399,12 @@ namespace rdar9136502 { y << x.i; // expected-error{{a bound member function may only be called}} } } + +namespace rdar9222009 { +class StringRef { + inline bool operator==(StringRef LHS, StringRef RHS) { // expected-error{{overloaded 'operator==' must be a binary operator (has 3 parameters)}} + return !(LHS == RHS); // expected-error{{invalid operands to binary expression ('rdar9222009::StringRef' and 'rdar9222009::StringRef')}} + } +}; + +}