Core 1591
Core 1591 * pt.c (unify_array_domain): Split out from unify. (unify): Use it for list deduction, too. From-SVN: r203725
This commit is contained in:
parent
fac91973cc
commit
06ea137631
3 changed files with 96 additions and 61 deletions
|
@ -1,5 +1,9 @@
|
|||
2013-10-16 Jason Merrill <jason@redhat.com>
|
||||
|
||||
Core 1591
|
||||
* pt.c (unify_array_domain): Split out from unify.
|
||||
(unify): Use it for list deduction, too.
|
||||
|
||||
PR c++/57850
|
||||
* decl2.c (dump_tu): Split out from...
|
||||
(cp_write_global_declarations): ...here. Call it in PCH mode.
|
||||
|
|
146
gcc/cp/pt.c
146
gcc/cp/pt.c
|
@ -17007,6 +17007,72 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms,
|
|||
return unify_success (explain_p);
|
||||
}
|
||||
|
||||
/* Handle unification of the domain of an array. PARM_DOM and ARG_DOM are
|
||||
INTEGER_TYPEs representing the TYPE_DOMAIN of ARRAY_TYPEs. The other
|
||||
parameters and return value are as for unify. */
|
||||
|
||||
static int
|
||||
unify_array_domain (tree tparms, tree targs,
|
||||
tree parm_dom, tree arg_dom,
|
||||
bool explain_p)
|
||||
{
|
||||
tree parm_max;
|
||||
tree arg_max;
|
||||
bool parm_cst;
|
||||
bool arg_cst;
|
||||
|
||||
/* Our representation of array types uses "N - 1" as the
|
||||
TYPE_MAX_VALUE for an array with "N" elements, if "N" is
|
||||
not an integer constant. We cannot unify arbitrarily
|
||||
complex expressions, so we eliminate the MINUS_EXPRs
|
||||
here. */
|
||||
parm_max = TYPE_MAX_VALUE (parm_dom);
|
||||
parm_cst = TREE_CODE (parm_max) == INTEGER_CST;
|
||||
if (!parm_cst)
|
||||
{
|
||||
gcc_assert (TREE_CODE (parm_max) == MINUS_EXPR);
|
||||
parm_max = TREE_OPERAND (parm_max, 0);
|
||||
}
|
||||
arg_max = TYPE_MAX_VALUE (arg_dom);
|
||||
arg_cst = TREE_CODE (arg_max) == INTEGER_CST;
|
||||
if (!arg_cst)
|
||||
{
|
||||
/* The ARG_MAX may not be a simple MINUS_EXPR, if we are
|
||||
trying to unify the type of a variable with the type
|
||||
of a template parameter. For example:
|
||||
|
||||
template <unsigned int N>
|
||||
void f (char (&) [N]);
|
||||
int g();
|
||||
void h(int i) {
|
||||
char a[g(i)];
|
||||
f(a);
|
||||
}
|
||||
|
||||
Here, the type of the ARG will be "int [g(i)]", and
|
||||
may be a SAVE_EXPR, etc. */
|
||||
if (TREE_CODE (arg_max) != MINUS_EXPR)
|
||||
return unify_vla_arg (explain_p, arg_dom);
|
||||
arg_max = TREE_OPERAND (arg_max, 0);
|
||||
}
|
||||
|
||||
/* If only one of the bounds used a MINUS_EXPR, compensate
|
||||
by adding one to the other bound. */
|
||||
if (parm_cst && !arg_cst)
|
||||
parm_max = fold_build2_loc (input_location, PLUS_EXPR,
|
||||
integer_type_node,
|
||||
parm_max,
|
||||
integer_one_node);
|
||||
else if (arg_cst && !parm_cst)
|
||||
arg_max = fold_build2_loc (input_location, PLUS_EXPR,
|
||||
integer_type_node,
|
||||
arg_max,
|
||||
integer_one_node);
|
||||
|
||||
return unify (tparms, targs, parm_max, arg_max,
|
||||
UNIFY_ALLOW_INTEGER, explain_p);
|
||||
}
|
||||
|
||||
/* Deduce the value of template parameters. TPARMS is the (innermost)
|
||||
set of template parameters to a template. TARGS is the bindings
|
||||
for those template parameters, as determined thus far; TARGS may
|
||||
|
@ -17092,13 +17158,17 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
|
|||
&& flag_deduce_init_list)
|
||||
parm = listify (parm);
|
||||
|
||||
if (!is_std_init_list (parm))
|
||||
if (!is_std_init_list (parm)
|
||||
&& TREE_CODE (parm) != ARRAY_TYPE)
|
||||
/* We can only deduce from an initializer list argument if the
|
||||
parameter is std::initializer_list; otherwise this is a
|
||||
non-deduced context. */
|
||||
parameter is std::initializer_list or an array; otherwise this
|
||||
is a non-deduced context. */
|
||||
return unify_success (explain_p);
|
||||
|
||||
elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (parm), 0);
|
||||
if (TREE_CODE (parm) == ARRAY_TYPE)
|
||||
elttype = TREE_TYPE (parm);
|
||||
else
|
||||
elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (parm), 0);
|
||||
|
||||
FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (arg), i, elt)
|
||||
{
|
||||
|
@ -17121,6 +17191,15 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
|
|||
explain_p);
|
||||
}
|
||||
|
||||
if (TREE_CODE (parm) == ARRAY_TYPE)
|
||||
{
|
||||
/* Also deduce from the length of the initializer list. */
|
||||
tree max = size_int (CONSTRUCTOR_NELTS (arg));
|
||||
tree idx = compute_array_index_type (NULL_TREE, max, tf_none);
|
||||
return unify_array_domain (tparms, targs, TYPE_DOMAIN (parm),
|
||||
idx, explain_p);
|
||||
}
|
||||
|
||||
/* If the std::initializer_list<T> deduction worked, replace the
|
||||
deduced A with std::initializer_list<A>. */
|
||||
if (orig_parm != parm)
|
||||
|
@ -17494,63 +17573,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
|
|||
RECUR_AND_CHECK_FAILURE (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg),
|
||||
strict & UNIFY_ALLOW_MORE_CV_QUAL, explain_p);
|
||||
if (TYPE_DOMAIN (parm) != NULL_TREE)
|
||||
{
|
||||
tree parm_max;
|
||||
tree arg_max;
|
||||
bool parm_cst;
|
||||
bool arg_cst;
|
||||
|
||||
/* Our representation of array types uses "N - 1" as the
|
||||
TYPE_MAX_VALUE for an array with "N" elements, if "N" is
|
||||
not an integer constant. We cannot unify arbitrarily
|
||||
complex expressions, so we eliminate the MINUS_EXPRs
|
||||
here. */
|
||||
parm_max = TYPE_MAX_VALUE (TYPE_DOMAIN (parm));
|
||||
parm_cst = TREE_CODE (parm_max) == INTEGER_CST;
|
||||
if (!parm_cst)
|
||||
{
|
||||
gcc_assert (TREE_CODE (parm_max) == MINUS_EXPR);
|
||||
parm_max = TREE_OPERAND (parm_max, 0);
|
||||
}
|
||||
arg_max = TYPE_MAX_VALUE (TYPE_DOMAIN (arg));
|
||||
arg_cst = TREE_CODE (arg_max) == INTEGER_CST;
|
||||
if (!arg_cst)
|
||||
{
|
||||
/* The ARG_MAX may not be a simple MINUS_EXPR, if we are
|
||||
trying to unify the type of a variable with the type
|
||||
of a template parameter. For example:
|
||||
|
||||
template <unsigned int N>
|
||||
void f (char (&) [N]);
|
||||
int g();
|
||||
void h(int i) {
|
||||
char a[g(i)];
|
||||
f(a);
|
||||
}
|
||||
|
||||
Here, the type of the ARG will be "int [g(i)]", and
|
||||
may be a SAVE_EXPR, etc. */
|
||||
if (TREE_CODE (arg_max) != MINUS_EXPR)
|
||||
return unify_vla_arg (explain_p, arg);
|
||||
arg_max = TREE_OPERAND (arg_max, 0);
|
||||
}
|
||||
|
||||
/* If only one of the bounds used a MINUS_EXPR, compensate
|
||||
by adding one to the other bound. */
|
||||
if (parm_cst && !arg_cst)
|
||||
parm_max = fold_build2_loc (input_location, PLUS_EXPR,
|
||||
integer_type_node,
|
||||
parm_max,
|
||||
integer_one_node);
|
||||
else if (arg_cst && !parm_cst)
|
||||
arg_max = fold_build2_loc (input_location, PLUS_EXPR,
|
||||
integer_type_node,
|
||||
arg_max,
|
||||
integer_one_node);
|
||||
|
||||
RECUR_AND_CHECK_FAILURE (tparms, targs, parm_max, arg_max,
|
||||
UNIFY_ALLOW_INTEGER, explain_p);
|
||||
}
|
||||
return unify_array_domain (tparms, targs, TYPE_DOMAIN (parm),
|
||||
TYPE_DOMAIN (arg), explain_p);
|
||||
return unify_success (explain_p);
|
||||
|
||||
case REAL_TYPE:
|
||||
|
|
7
gcc/testsuite/g++.dg/cpp0x/initlist74.C
Normal file
7
gcc/testsuite/g++.dg/cpp0x/initlist74.C
Normal file
|
@ -0,0 +1,7 @@
|
|||
// Core 1591
|
||||
// { dg-require-effective-target c++11 }
|
||||
|
||||
template<class T, int N> void g(T const (&)[N]);
|
||||
void f() {
|
||||
g( { 1, 2, 3, 4 } );
|
||||
}
|
Loading…
Add table
Reference in a new issue