diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index f97e244120612..858654e35cbb6 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -12107,9 +12107,12 @@ struct CompareOverloadCandidatesForDisplay { if (RFailureKind != ovl_fail_bad_deduction) return true; - if (L->DeductionFailure.Result != R->DeductionFailure.Result) - return RankDeductionFailure(L->DeductionFailure) - < RankDeductionFailure(R->DeductionFailure); + if (L->DeductionFailure.Result != R->DeductionFailure.Result) { + unsigned LRank = RankDeductionFailure(L->DeductionFailure); + unsigned RRank = RankDeductionFailure(R->DeductionFailure); + if (LRank != RRank) + return LRank < RRank; + } } else if (RFailureKind == ovl_fail_bad_deduction) return false; diff --git a/clang/test/SemaCXX/overloaded-operators-display-order-crash.cpp b/clang/test/SemaCXX/overloaded-operators-display-order-crash.cpp index 5abd048f1d136..79e2840583b5d 100644 --- a/clang/test/SemaCXX/overloaded-operators-display-order-crash.cpp +++ b/clang/test/SemaCXX/overloaded-operators-display-order-crash.cpp @@ -52,3 +52,17 @@ namespace bad_conversion { // CHECK-NEXT: void func(double*, int, int) } } + +namespace bad_deduction { + template struct templ {}; + template void func(templ); + template void func(T*); + template auto func(T&) -> decltype(T().begin()); + template auto func(const T&) -> decltype(T().begin()); + + bool doit() { + struct record {} r; + func(r); // expected-error {{no matching function for call to 'func'}} + // expected-note@* 4{{candidate}} + } +}