* 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
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.
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. */
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;
}
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);
--- /dev/null
+// 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;