summaryrefslogtreecommitdiff
path: root/test/CXX
diff options
context:
space:
mode:
authorFaisal Vali <faisalv@yahoo.com>2017-10-22 14:45:08 +0000
committerFaisal Vali <faisalv@yahoo.com>2017-10-22 14:45:08 +0000
commitf027325999d75572cbdb4dda2e475bd27bcc74da (patch)
tree430972a96506089bf472bb94193eb41ae15bf718 /test/CXX
parentb99743553a954ef2e92d143890fe987500088ff8 (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.cpp6
-rw-r--r--test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp37
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