diff options
author | Faisal Vali <faisalv@yahoo.com> | 2017-10-22 14:45:08 +0000 |
---|---|---|
committer | Faisal Vali <faisalv@yahoo.com> | 2017-10-22 14:45:08 +0000 |
commit | f027325999d75572cbdb4dda2e475bd27bcc74da (patch) | |
tree | 430972a96506089bf472bb94193eb41ae15bf718 /test/CXX | |
parent | b99743553a954ef2e92d143890fe987500088ff8 (diff) |
[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
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@316292 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CXX')
-rw-r--r-- | test/CXX/over/over.match/over.match.best/p1.cpp | 6 | ||||
-rw-r--r-- | test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp | 37 |
2 files changed, 37 insertions, 6 deletions
diff --git a/test/CXX/over/over.match/over.match.best/p1.cpp b/test/CXX/over/over.match/over.match.best/p1.cpp index fad5bf9a72..a933f62a30 100644 --- a/test/CXX/over/over.match/over.match.best/p1.cpp +++ b/test/CXX/over/over.match/over.match.best/p1.cpp @@ -25,13 +25,13 @@ namespace deduction_guide_example { // FIXME: The standard's example is wrong; we add a remove_ref<...> here to // fix it. - template<typename T, int N = remove_ref<T>::value> A(T&&, int*) -> A<T>; + template<typename T, int N = remove_ref<T>::value> A(T&&, int*) -> A<T**>; A a{1, 0}; extern A<int> a; - A b{a, 0}; + A b{a, 0}; // uses the implicit ctor that is more specialized A<int> *pa = &a; - A<A<int>&> *pb = &b; + A<int> *pb = &b; } // Partial ordering of function template specializations will be tested diff --git a/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp b/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp index cf925455ac..cb9541caad 100644 --- a/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp +++ b/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp @@ -6,9 +6,10 @@ namespace Explicit { template<typename T> struct A { A(T); A(T*); + A(...); }; template<typename T> A(T) -> A<T>; - template<typename T> explicit A(T*) -> A<T>; // expected-note {{explicit}} + template<typename T> explicit A(T*) -> A<T**>; // expected-note {{explicit}} int *p; A a(p); @@ -16,14 +17,15 @@ namespace Explicit { A c{p}; A d = {p}; // expected-error {{selected an explicit deduction guide}} - using X = A<int>; - using Y = A<int*>; + using X = A<int**>; + using Y = A<int>; // uses the implicit guide, being more specialized than the eligible user-defined deduction guides. using X = decltype(a); using Y = decltype(b); using X = decltype(c); } + namespace std { template<typename T> struct initializer_list { const T *ptr; @@ -54,3 +56,32 @@ namespace p0702r1 { // between X<int> and X<float>. X xz = {z}; // expected-error {{no viable constructor or deduction guide}} } +namespace pr34970 { +//https://bugs.llvm.org/show_bug.cgi?id=34970 + +template <typename X, typename Y> struct IsSame { + static constexpr bool value = false; +}; + +template <typename Z> struct IsSame<Z, Z> { + static constexpr bool value = true; +}; + +template <typename T> struct Optional { + template <typename U> Optional(U&&) { } +}; + +template <typename A> Optional(A) -> Optional<A>; + +int main() { + Optional opt(1729); + Optional dupe(opt); + + static_assert(IsSame<decltype(opt), Optional<int>>::value); + static_assert(IsSame<decltype(dupe), Optional<int>>::value); + static_assert(!IsSame<decltype(dupe), Optional<Optional<int>>>::value); + return 0; +} + + +}
\ No newline at end of file |