Skip to content

Commit 1d33f8d

Browse files
committed
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 <rdar://problem/9222009>. llvm-svn: 130902
1 parent 85c011d commit 1d33f8d

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

clang/lib/Sema/SemaOverload.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6676,6 +6676,15 @@ void DiagnoseArityMismatch(Sema &S, OverloadCandidate *Cand,
66766676

66776677
unsigned MinParams = Fn->getMinRequiredArguments();
66786678

6679+
// With invalid overloaded operators, it's possible that we think we
6680+
// have an arity mismatch when it fact it looks like we have the
6681+
// right number of arguments, because only overloaded operators have
6682+
// the weird behavior of overloading member and non-member functions.
6683+
// Just don't report anything.
6684+
if (Fn->isInvalidDecl() &&
6685+
Fn->getDeclName().getNameKind() == DeclarationName::CXXOperatorName)
6686+
return;
6687+
66796688
// at least / at most / exactly
66806689
unsigned mode, modeCount;
66816690
if (NumFormalArgs < MinParams) {

clang/test/SemaCXX/overloaded-operator.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ struct A {
3333

3434
A make_A();
3535

36-
bool operator==(A&, Z&); // expected-note 2{{candidate function}}
36+
bool operator==(A&, Z&); // expected-note 3{{candidate function}}
3737

3838
void h(A a, const A ac, Z z) {
3939
make_A() == z;
@@ -68,7 +68,7 @@ struct E2 {
6868
};
6969

7070
// C++ [over.match.oper]p3 - enum restriction.
71-
float& operator==(E1, E2);
71+
float& operator==(E1, E2); // expected-note{{candidate function}}
7272

7373
void enum_test(Enum1 enum1, Enum2 enum2, E1 e1, E2 e2, Enum1 next_enum1) {
7474
float &f1 = (e1 == e2);
@@ -85,8 +85,8 @@ class pr5244_foo
8585
pr5244_foo(char);
8686
};
8787

88-
bool operator==(const pr5244_foo& s1, const pr5244_foo& s2);
89-
bool operator==(char c, const pr5244_foo& s);
88+
bool operator==(const pr5244_foo& s1, const pr5244_foo& s2); // expected-note{{candidate function}}
89+
bool operator==(char c, const pr5244_foo& s); // expected-note{{candidate function}}
9090

9191
enum pr5244_bar
9292
{
@@ -399,3 +399,12 @@ namespace rdar9136502 {
399399
y << x.i; // expected-error{{a bound member function may only be called}}
400400
}
401401
}
402+
403+
namespace rdar9222009 {
404+
class StringRef {
405+
inline bool operator==(StringRef LHS, StringRef RHS) { // expected-error{{overloaded 'operator==' must be a binary operator (has 3 parameters)}}
406+
return !(LHS == RHS); // expected-error{{invalid operands to binary expression ('rdar9222009::StringRef' and 'rdar9222009::StringRef')}}
407+
}
408+
};
409+
410+
}

0 commit comments

Comments
 (0)