From 1db66e705f4dbe7dbe17edac804289ef59d5f616 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Thu, 30 Jan 2020 18:40:53 -0800 Subject: [PATCH] PR44627: Consider reversing == and <=> candidates found by ADL. --- clang/lib/Sema/SemaOverload.cpp | 30 ++++++++++++++----- .../class.compare.default/p4.cpp | 2 +- .../over.match.oper/p3-2a.cpp | 12 ++++++++ 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index f10e54851434a..a244868d52604 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -9278,17 +9278,31 @@ Sema::AddArgumentDependentLookupCandidates(DeclarationName Name, if (ExplicitTemplateArgs) continue; - AddOverloadCandidate(FD, FoundDecl, Args, CandidateSet, - /*SuppressUserConversions=*/false, PartialOverloading, - /*AllowExplicit*/ true, - /*AllowExplicitConversions*/ false, - ADLCallKind::UsesADL); + AddOverloadCandidate( + FD, FoundDecl, Args, CandidateSet, /*SuppressUserConversions=*/false, + PartialOverloading, /*AllowExplicit=*/true, + /*AllowExplicitConversions=*/false, ADLCallKind::UsesADL); + if (CandidateSet.getRewriteInfo().shouldAddReversed(Context, FD)) { + AddOverloadCandidate( + FD, FoundDecl, {Args[1], Args[0]}, CandidateSet, + /*SuppressUserConversions=*/false, PartialOverloading, + /*AllowExplicit=*/true, /*AllowExplicitConversions=*/false, + ADLCallKind::UsesADL, None, OverloadCandidateParamOrder::Reversed); + } } else { + auto *FTD = cast(*I); AddTemplateOverloadCandidate( - cast(*I), FoundDecl, ExplicitTemplateArgs, Args, - CandidateSet, + FTD, FoundDecl, ExplicitTemplateArgs, Args, CandidateSet, /*SuppressUserConversions=*/false, PartialOverloading, - /*AllowExplicit*/true, ADLCallKind::UsesADL); + /*AllowExplicit=*/true, ADLCallKind::UsesADL); + if (CandidateSet.getRewriteInfo().shouldAddReversed( + Context, FTD->getTemplatedDecl())) { + AddTemplateOverloadCandidate( + FTD, FoundDecl, ExplicitTemplateArgs, {Args[1], Args[0]}, + CandidateSet, /*SuppressUserConversions=*/false, PartialOverloading, + /*AllowExplicit=*/true, ADLCallKind::UsesADL, + OverloadCandidateParamOrder::Reversed); + } } } } diff --git a/clang/test/CXX/class/class.compare/class.compare.default/p4.cpp b/clang/test/CXX/class/class.compare/class.compare.default/p4.cpp index 3820b5b442876..8c303c63d899d 100644 --- a/clang/test/CXX/class/class.compare/class.compare.default/p4.cpp +++ b/clang/test/CXX/class/class.compare/class.compare.default/p4.cpp @@ -122,7 +122,7 @@ namespace NoInjectionIfOperatorEqualsDeclared { bool test_a = A() == A(); // expected-error {{invalid operands}} struct B { - friend void operator==(int, struct Q); // expected-note {{not viable}} + friend void operator==(int, struct Q); // expected-note 2{{not viable}} std::strong_ordering operator<=>(const B&) const = default; }; bool test_b = B() == B(); // expected-error {{invalid operands}} diff --git a/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp b/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp index 3be8dc7749c6f..023e076d50a73 100644 --- a/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp +++ b/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp @@ -113,6 +113,18 @@ namespace bullet4 { X<3> reversed_add = x2 + x1; // expected-error {{invalid operands}} } +namespace PR44627 { + namespace ADL { + struct type {}; + bool operator==(type lhs, int rhs) { + return true; + } + } + + bool b1 = ADL::type() == 0; + bool b2 = 0 == ADL::type(); +} + // Various C++17 cases that are known to be broken by the C++20 rules. namespace problem_cases { // We can have an ambiguity between an operator and its reversed form. This