Commit d1a902a2 by Jason Merrill Committed by Jason Merrill

re PR c++/60992 (ICE in tsubst_copy, at cp/pt.c:12637)

	PR c++/60992
	* pt.c (tsubst_init): Split out from...
	(tsubst_expr) [DECL_EXPR]: Here.
	(tsubst_copy) [VAR_DECL]: Use it.
	* semantics.c (finish_id_expression): Return the decl for static/const.

From-SVN: r211084
parent 7480a39b
2014-05-30 Jason Merrill <jason@redhat.com>
PR c++/60992
* pt.c (tsubst_init): Split out from...
(tsubst_expr) [DECL_EXPR]: Here.
(tsubst_copy) [VAR_DECL]: Use it.
* semantics.c (finish_id_expression): Return the decl for static/const.
2014-05-28 Jason Merrill <jason@redhat.com>
PR c++/47202
......
......@@ -12513,6 +12513,37 @@ tsubst_qualified_id (tree qualified_id, tree args,
return expr;
}
/* tsubst the initializer for a VAR_DECL. INIT is the unsubstituted
initializer, DECL is the substituted VAR_DECL. Other arguments are as
for tsubst. */
static tree
tsubst_init (tree init, tree decl, tree args,
tsubst_flags_t complain, tree in_decl)
{
if (!init)
return NULL_TREE;
init = tsubst_expr (init, args, complain, in_decl, false);
if (!init)
{
/* If we had an initializer but it
instantiated to nothing,
value-initialize the object. This will
only occur when the initializer was a
pack expansion where the parameter packs
used in that expansion were of length
zero. */
init = build_value_init (TREE_TYPE (decl),
complain);
if (TREE_CODE (init) == AGGR_INIT_EXPR)
init = get_target_expr_sfinae (init, complain);
}
return init;
}
/* Like tsubst, but deals with expressions. This function just replaces
template parms; to finish processing the resultant expression, use
tsubst_copy_and_build or tsubst_expr. */
......@@ -12670,11 +12701,34 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
local static or constant. Building a new VAR_DECL
should be OK in all those cases. */
r = tsubst_decl (t, args, complain);
if (decl_constant_var_p (r))
/* A use of a local constant must decay to its value. */
return integral_constant_value (r);
if (decl_maybe_constant_var_p (r))
{
/* We can't call cp_finish_decl, so handle the
initializer by hand. */
tree init = tsubst_init (DECL_INITIAL (t), r, args,
complain, in_decl);
if (!processing_template_decl)
init = maybe_constant_init (init);
if (processing_template_decl
? potential_constant_expression (init)
: reduced_constant_expression_p (init))
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r)
= TREE_CONSTANT (r) = true;
DECL_INITIAL (r) = init;
}
gcc_assert (cp_unevaluated_operand || TREE_STATIC (r)
|| decl_constant_var_p (r)
|| errorcount || sorrycount);
if (!processing_template_decl)
{
if (TREE_STATIC (r))
rest_of_decl_compilation (r, toplevel_bindings_p (),
at_eof);
else if (decl_constant_var_p (r))
/* A use of a local constant decays to its value.
FIXME update for core DR 696. */
return integral_constant_value (r);
}
return r;
}
}
......@@ -13544,26 +13598,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
init = cp_fname_init (name, &TREE_TYPE (decl));
}
else
{
tree t = RECUR (init);
if (init && !t)
{
/* If we had an initializer but it
instantiated to nothing,
value-initialize the object. This will
only occur when the initializer was a
pack expansion where the parameter packs
used in that expansion were of length
zero. */
init = build_value_init (TREE_TYPE (decl),
complain);
if (TREE_CODE (init) == AGGR_INIT_EXPR)
init = get_target_expr_sfinae (init, complain);
}
else
init = t;
}
init = tsubst_init (init, decl, args, complain, in_decl);
if (VAR_P (decl))
const_init = (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P
......
......@@ -3166,12 +3166,7 @@ finish_id_expression (tree id_expression,
else if (TREE_STATIC (decl)
/* It's not a use (3.2) if we're in an unevaluated context. */
|| cp_unevaluated_operand)
{
if (processing_template_decl)
/* For a use of an outer static/unevaluated var, return the id
so that we'll look it up again in the instantiation. */
return id_expression;
}
/* OK */;
else
{
tree context = DECL_CONTEXT (decl);
......@@ -3190,13 +3185,13 @@ finish_id_expression (tree id_expression,
the complexity of the problem"
FIXME update for final resolution of core issue 696. */
if (decl_constant_var_p (decl))
if (decl_maybe_constant_var_p (decl))
{
if (processing_template_decl)
/* In a template, the constant value may not be in a usable
form, so look it up again at instantiation time. */
return id_expression;
else
form, so wait until instantiation time. */
return decl;
else if (decl_constant_var_p (decl))
return integral_constant_value (decl);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment