Skip to content

Commit 7e6d965

Browse files
author
jason
committed
P0512R0 - Deduction from an initializer list.
* pt.c (do_class_deduction): Do list deduction in two phases. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@250183 138bc75d-0d04-0410-961f-82ee72b054a4
1 parent 7c25ba4 commit 7e6d965

File tree

3 files changed

+78
-11
lines changed

3 files changed

+78
-11
lines changed

gcc/cp/ChangeLog

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
2017-07-12 Jason Merrill <[email protected]>
2+
3+
P0512R0 - Deduction from an initializer list.
4+
* pt.c (do_class_deduction): Do list deduction in two phases.
5+
16
2017-07-12 Nathan Sidwell <[email protected]>
27

38
* cp-tree.h (DECL_CONSTRUCTOR_P, DECL_MAYBE_IN_CHARGE_CONSTRUCTOR,

gcc/cp/pt.c

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25329,14 +25329,20 @@ do_class_deduction (tree ptype, tree tmpl, tree init, int flags,
2532925329

2533025330
tree type = TREE_TYPE (tmpl);
2533125331

25332+
bool try_list_ctor = false;
25333+
2533225334
vec<tree,va_gc> *args;
2533325335
if (init == NULL_TREE
2533425336
|| TREE_CODE (init) == TREE_LIST)
2533525337
args = make_tree_vector_from_list (init);
25336-
else if (BRACE_ENCLOSED_INITIALIZER_P (init)
25337-
&& !TYPE_HAS_LIST_CTOR (type)
25338-
&& !is_std_init_list (type))
25339-
args = make_tree_vector_from_ctor (init);
25338+
else if (BRACE_ENCLOSED_INITIALIZER_P (init))
25339+
{
25340+
try_list_ctor = TYPE_HAS_LIST_CTOR (type);
25341+
if (try_list_ctor || is_std_init_list (type))
25342+
args = make_tree_vector_single (init);
25343+
else
25344+
args = make_tree_vector_from_ctor (init);
25345+
}
2534025346
else
2534125347
args = make_tree_vector_single (init);
2534225348

@@ -25391,13 +25397,43 @@ do_class_deduction (tree ptype, tree tmpl, tree init, int flags,
2539125397
saw_ctor = true;
2539225398
}
2539325399

25394-
if (args->length () < 2)
25400+
tree call = error_mark_node;
25401+
25402+
/* If this is list-initialization and the class has a list constructor, first
25403+
try deducing from the list as a single argument, as [over.match.list]. */
25404+
tree list_cands = NULL_TREE;
25405+
if (try_list_ctor && cands)
25406+
for (lkp_iterator iter (cands); iter; ++iter)
25407+
{
25408+
tree dg = *iter;
25409+
if (is_list_ctor (dg))
25410+
list_cands = lookup_add (dg, list_cands);
25411+
}
25412+
if (list_cands)
25413+
{
25414+
++cp_unevaluated_operand;
25415+
call = build_new_function_call (list_cands, &args, tf_decltype);
25416+
--cp_unevaluated_operand;
25417+
25418+
if (call == error_mark_node)
25419+
{
25420+
/* That didn't work, now try treating the list as a sequence of
25421+
arguments. */
25422+
release_tree_vector (args);
25423+
args = make_tree_vector_from_ctor (init);
25424+
}
25425+
}
25426+
25427+
/* Maybe generate an implicit deduction guide. */
25428+
if (call == error_mark_node && args->length () < 2)
2539525429
{
2539625430
tree gtype = NULL_TREE;
2539725431

2539825432
if (args->length () == 1)
25433+
/* Generate a copy guide. */
2539925434
gtype = build_reference_type (type);
2540025435
else if (!saw_ctor)
25436+
/* Generate a default guide. */
2540125437
gtype = type;
2540225438

2540325439
if (gtype)
@@ -25419,22 +25455,29 @@ do_class_deduction (tree ptype, tree tmpl, tree init, int flags,
2541925455
return error_mark_node;
2542025456
}
2542125457

25422-
++cp_unevaluated_operand;
25423-
tree t = build_new_function_call (cands, &args, tf_decltype);
25458+
if (call == error_mark_node)
25459+
{
25460+
++cp_unevaluated_operand;
25461+
call = build_new_function_call (cands, &args, tf_decltype);
25462+
--cp_unevaluated_operand;
25463+
}
2542425464

25425-
if (t == error_mark_node && (complain & tf_warning_or_error))
25465+
if (call == error_mark_node && (complain & tf_warning_or_error))
2542625466
{
2542725467
error ("class template argument deduction failed:");
25428-
t = build_new_function_call (cands, &args, complain | tf_decltype);
25468+
25469+
++cp_unevaluated_operand;
25470+
call = build_new_function_call (cands, &args, complain | tf_decltype);
25471+
--cp_unevaluated_operand;
25472+
2542925473
if (elided)
2543025474
inform (input_location, "explicit deduction guides not considered "
2543125475
"for copy-initialization");
2543225476
}
2543325477

25434-
--cp_unevaluated_operand;
2543525478
release_tree_vector (args);
2543625479

25437-
return cp_build_qualified_type (TREE_TYPE (t), cp_type_quals (ptype));
25480+
return cp_build_qualified_type (TREE_TYPE (call), cp_type_quals (ptype));
2543825481
}
2543925482

2544025483
/* Replace occurrences of 'auto' in TYPE with the appropriate type deduced
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// { dg-options -std=c++1z }
2+
3+
#include <initializer_list>
4+
5+
struct B { };
6+
7+
template <class T>
8+
struct A
9+
{
10+
A(std::initializer_list<T>);
11+
A(T, B);
12+
};
13+
14+
A a { 1, B() };
15+
16+
template <class,class> struct same;
17+
template <class T> struct same<T,T> { };
18+
19+
same<decltype(a), A<int>> s;

0 commit comments

Comments
 (0)