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
This commit is contained in:
Jason Merrill 2017-01-19 23:43:13 -05:00 committed by Jason Merrill
parent a3a1620bb8
commit 689f867c9c
4 changed files with 46 additions and 2 deletions

View file

@ -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.

View file

@ -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. */

View file

@ -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);

View file

@ -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;