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:
parent
a3a1620bb8
commit
689f867c9c
4 changed files with 46 additions and 2 deletions
|
@ -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.
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
|
24
gcc/testsuite/g++.dg/cpp1z/class-deduction25.C
Normal file
24
gcc/testsuite/g++.dg/cpp1z/class-deduction25.C
Normal 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;
|
Loading…
Add table
Reference in a new issue