aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2017-01-19 23:43:13 -0500
committerJason Merrill <jason@gcc.gnu.org>2017-01-19 23:43:13 -0500
commit689f867c9c8668f864520372562f8e1b3ca7137c (patch)
tree1c8ef26acf7c7f2e37d0cd34a5c207a850688c04
parenta3a1620bb840d62dbde06ce0290e8e5cfcbbf18b (diff)
downloadgcc-689f867c9c8668f864520372562f8e1b3ca7137c.zip
gcc-689f867c9c8668f864520372562f8e1b3ca7137c.tar.gz
gcc-689f867c9c8668f864520372562f8e1b3ca7137c.tar.bz2
US 19 - deduction guides and constructors
* call.c (joust): Prefer deduction guides to constructors. * pt.c (build_deduction_guide): Set DECL_ARTIFICIAL. (deduction_guide_p): Check DECL_P. From-SVN: r244681
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/call.c12
-rw-r--r--gcc/cp/pt.c7
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/class-deduction25.C24
4 files changed, 46 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 90e230f..e168539 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,10 @@
2017-01-19 Jason Merrill <jason@redhat.com>
+ US 19 - deduction guides and constructors
+ * call.c (joust): Prefer deduction guides to constructors.
+ * pt.c (build_deduction_guide): Set DECL_ARTIFICIAL.
+ (deduction_guide_p): Check DECL_P.
+
* decl.c (check_initializer): Always use build_aggr_init for array
decomposition.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 88d83dd..0059a395 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -9633,6 +9633,18 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn,
return winner;
}
+ /* F1 is generated from a deduction-guide (13.3.1.8) and F2 is not */
+ if (deduction_guide_p (cand1->fn))
+ {
+ gcc_assert (deduction_guide_p (cand2->fn));
+ /* We distinguish between candidates from an explicit deduction guide and
+ candidates built from a constructor based on DECL_ARTIFICIAL. */
+ int art1 = DECL_ARTIFICIAL (cand1->fn);
+ int art2 = DECL_ARTIFICIAL (cand2->fn);
+ if (art1 != art2)
+ return art2 - art1;
+ }
+
/* or, if not that,
F1 is a non-template function and F2 is a template function
specialization. */
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index c679133..f683727 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -24776,8 +24776,9 @@ dguide_name_p (tree name)
bool
deduction_guide_p (tree fn)
{
- if (tree name = DECL_NAME (fn))
- return dguide_name_p (name);
+ if (DECL_P (fn))
+ if (tree name = DECL_NAME (fn))
+ return dguide_name_p (name);
return false;
}
@@ -24981,7 +24982,9 @@ build_deduction_guide (tree ctor, tree outer_args, tsubst_flags_t complain)
FUNCTION_DECL,
dguide_name (type), fntype);
DECL_ARGUMENTS (ded_fn) = fargs;
+ DECL_ARTIFICIAL (ded_fn) = true;
tree ded_tmpl = build_template_decl (ded_fn, tparms, /*member*/false);
+ DECL_ARTIFICIAL (ded_tmpl) = true;
DECL_TEMPLATE_RESULT (ded_tmpl) = ded_fn;
TREE_TYPE (ded_tmpl) = TREE_TYPE (ded_fn);
DECL_TEMPLATE_INFO (ded_fn) = build_template_info (ded_tmpl, targs);
diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction25.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction25.C
new file mode 100644
index 0000000..07ab5f5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction25.C
@@ -0,0 +1,24 @@
+// Testcase from P0512R0 for C++17 NB comment US 19
+// { dg-options -std=c++1z }
+
+template<typename> struct remove_ref;
+template<typename _Tp> struct remove_ref { typedef _Tp type; };
+template<typename _Tp> struct remove_ref<_Tp&> { typedef _Tp type; };
+template<typename _Tp> struct remove_ref<_Tp&&> { typedef _Tp type; };
+template<typename _Tp> using remove_ref_t = typename remove_ref<_Tp>::type;
+
+template<class T> struct A {
+ A(T, int*); // #1
+ A(A<T>&, int*); // #2
+ enum { value };
+};
+template<class T, int N = remove_ref_t<T>::value> A(T&&, int*) -> A<T>; //#3
+
+A a{1,0}; // uses #1 to deduce A<int> and initializes with #1
+A b{a,0}; // uses #3 (not #2) to deduce A<A<int>&> and initializes with #1
+
+template <class,class> struct same;
+template <class T> struct same<T,T> {};
+
+same<decltype(a),A<int>> s1;
+same<decltype(b),A<A<int>&>> s2;