[C++17] Fix PR34970 - tweak overload resolution for class template deduction-guides in line with WG21's p0620r0.
In order to identify the copy deduction candidate, I considered two approaches:
- attempt to determine whether an implicit guide is a copy deduction candidate by checking certain properties of its subsituted parameter during overload-resolution.
- using one of the many bits (WillHaveBody) from FunctionDecl (that CXXDeductionGuideDecl inherits from) that are otherwise irrelevant for deduction guides
After some brittle gymnastics w the first strategy, I settled on the second, although to avoid confusion and to give that bit a better name, i turned it into a member of an anonymous union.
Given this identification 'bit', the tweak to overload resolution was a simple reordering of the deduction guide checks (in SemaOverload.cpp::isBetterOverloadCandidate), in-line with Jason Merrill's p0620r0 drafting which made it into the working paper. Concordant with that, I made sure the copy deduction candidate is always added.
References:
See https://bugs.llvm.org/show_bug.cgi?id=34970
See http://wg21.link/p0620r0
llvm-svn: 316292
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 0e53ffa..49e9126 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -8965,12 +8965,6 @@
// C++14 [over.match.best]p1 section 2 bullet 3.
}
- // -- F1 is generated from a deduction-guide and F2 is not
- auto *Guide1 = dyn_cast_or_null<CXXDeductionGuideDecl>(Cand1.Function);
- auto *Guide2 = dyn_cast_or_null<CXXDeductionGuideDecl>(Cand2.Function);
- if (Guide1 && Guide2 && Guide1->isImplicit() != Guide2->isImplicit())
- return Guide2->isImplicit();
-
// -- F1 is a non-template function and F2 is a function template
// specialization, or, if not that,
bool Cand1IsSpecialization = Cand1.Function &&
@@ -9015,6 +9009,23 @@
// Inherited from sibling base classes: still ambiguous.
}
+ // Check C++17 tie-breakers for deduction guides.
+ {
+ auto *Guide1 = dyn_cast_or_null<CXXDeductionGuideDecl>(Cand1.Function);
+ auto *Guide2 = dyn_cast_or_null<CXXDeductionGuideDecl>(Cand2.Function);
+ if (Guide1 && Guide2) {
+ // -- F1 is generated from a deduction-guide and F2 is not
+ if (Guide1->isImplicit() != Guide2->isImplicit())
+ return Guide2->isImplicit();
+
+ // -- F1 is the copy deduction candidate(16.3.1.8) and F2 is not
+ if (Guide1->isCopyDeductionCandidate())
+ return true;
+ }
+ }
+
+
+
// FIXME: Work around a defect in the C++17 guaranteed copy elision wording,
// as combined with the resolution to CWG issue 243.
//