Commit 9257f35f by Jason Merrill Committed by Jason Merrill

re PR c++/48446 (internal compiler error: in gimplify_var_or_parm_decl, at gimplify.c:1946)

	PR c++/48446
	* decl.c (stabilize_save_expr_r, stabilize_vla_size): New.
	(compute_array_index_type): Revert earlier 48446 changes.
	(grokdeclarator): Use stabilize_vla_size.

From-SVN: r173264
parent 6fb380f7
2011-05-02 Jason Merrill <jason@redhat.com>
PR c++/48446
* decl.c (stabilize_save_expr_r, stabilize_vla_size): New.
(compute_array_index_type): Revert earlier 48446 changes.
(grokdeclarator): Use stabilize_vla_size.
2011-05-02 Dmitry Gorbachev <d.g.gorbachev@gmail.com>
Eric Botcazou <ebotcazou@adacore.com>
......
......@@ -7576,6 +7576,38 @@ check_static_variable_definition (tree decl, tree type)
return 0;
}
/* *expr_p is part of the TYPE_SIZE of a variably-sized array. If any
SAVE_EXPRs in *expr_p wrap expressions with side-effects, break those
expressions out into temporary variables so that walk_tree doesn't
step into them (c++/15764). */
static tree
stabilize_save_expr_r (tree *expr_p, int *walk_subtrees, void *data)
{
struct pointer_set_t *pset = (struct pointer_set_t *)data;
tree expr = *expr_p;
if (TREE_CODE (expr) == SAVE_EXPR)
{
tree op = TREE_OPERAND (expr, 0);
cp_walk_tree (&op, stabilize_save_expr_r, data, pset);
if (TREE_SIDE_EFFECTS (op))
TREE_OPERAND (expr, 0) = get_temp_regvar (TREE_TYPE (op), op);
}
else if (!EXPR_P (expr))
*walk_subtrees = 0;
return NULL;
}
/* Entry point for the above. */
static void
stabilize_vla_size (tree size)
{
struct pointer_set_t *pset = pointer_set_create ();
/* Break out any function calls into temporary variables. */
cp_walk_tree (&size, stabilize_save_expr_r, pset, pset);
}
/* Given the SIZE (i.e., number of elements) in an array, compute an
appropriate index type for the array. If non-NULL, NAME is the
name of the thing being declared. */
......@@ -7769,16 +7801,8 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
processing_template_decl = saved_processing_template_decl;
if (!TREE_CONSTANT (itype))
{
/* A variable sized array. */
if (TREE_SIDE_EFFECTS (itype))
/* Use get_temp_regvar rather than variable_size here so that
people walking expressions that use a variable of this type
don't walk into this expression. */
itype = get_temp_regvar (TREE_TYPE (itype), itype);
else
itype = variable_size (itype);
}
/* A variable sized array. */
itype = variable_size (itype);
/* Make sure that there was no overflow when creating to a signed
index type. (For example, on a 32-bit machine, an array with
size 2^32 - 1 is too big.) */
......@@ -9051,7 +9075,12 @@ grokdeclarator (const cp_declarator *declarator,
&& (decl_context == NORMAL || decl_context == FIELD)
&& at_function_scope_p ()
&& variably_modified_type_p (type, NULL_TREE))
finish_expr_stmt (TYPE_SIZE (type));
{
/* First break out any side-effects. */
stabilize_vla_size (TYPE_SIZE (type));
/* And then force evaluation of the SAVE_EXPR. */
finish_expr_stmt (TYPE_SIZE (type));
}
if (declarator->kind == cdk_reference)
{
......@@ -9126,6 +9155,14 @@ grokdeclarator (const cp_declarator *declarator,
}
}
/* We need to stabilize side-effects in VLA sizes for regular array
declarations too, not just pointers to arrays. */
if (type != error_mark_node && !TYPE_NAME (type)
&& (decl_context == NORMAL || decl_context == FIELD)
&& at_function_scope_p ()
&& variably_modified_type_p (type, NULL_TREE))
stabilize_vla_size (TYPE_SIZE (type));
/* A `constexpr' specifier used in an object declaration declares
the object as `const'. */
if (constexpr_p && innermost_code != cdk_function)
......
2011-05-02 Jason Merrill <jason@redhat.com>
* c-c++-common/vla-1.c: New.
2011-05-02 Richard Guenther <rguenther@suse.de>
PR tree-optimization/48822
......
/* Test that changes to a variable are reflected in a VLA later in the
expression. */
/* { dg-options "" } */
#ifdef __cplusplus
extern "C"
#endif
void abort();
int i = 4;
int f()
{
return i;
}
int main()
{
if (i+=2, sizeof(*(int(*)[f()])0) != 6*sizeof(int))
abort();
return 0;
}
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