Commit 786025ea by Jakub Jelinek Committed by Jakub Jelinek

re PR c/33238 (ICE on statement expression using variable-sized structure in…

re PR c/33238 (ICE on statement expression using variable-sized structure in tree_low_cst, at tree.c:4502)

	PR c/33238
	PR c/27301
	* gimplify.c (gimplify_vla_decl): New function.
	(gimplify_decl_expr): Move VLA decl handling to gimplify_vla_decl.
	Call it.
	(gimplify_target_expr): Handle variable length TARGET_EXPRs.

	* gcc.c-torture/execute/20070919-1.c: New test.
	* gcc.dg/pr33238.c: New test.
	* gcc.dg/pr27301.c: New test.

From-SVN: r128629
parent 334a9543
2007-09-20 Jakub Jelinek <jakub@redhat.com>
PR c/33238
PR c/27301
* gimplify.c (gimplify_vla_decl): New function.
(gimplify_decl_expr): Move VLA decl handling to gimplify_vla_decl.
Call it.
(gimplify_target_expr): Handle variable length TARGET_EXPRs.
2007-09-20 Richard Sandiford <rsandifo@nildram.co.uk>
* doc/invoke.texi (-minterlink-mips16): Document.
......@@ -1211,31 +1211,9 @@ gimplify_return_expr (tree stmt, tree *pre_p)
return GS_ALL_DONE;
}
/* Gimplifies a DECL_EXPR node *STMT_P by making any necessary allocation
and initialization explicit. */
static enum gimplify_status
gimplify_decl_expr (tree *stmt_p)
static void
gimplify_vla_decl (tree decl, tree *stmt_p)
{
tree stmt = *stmt_p;
tree decl = DECL_EXPR_DECL (stmt);
*stmt_p = NULL_TREE;
if (TREE_TYPE (decl) == error_mark_node)
return GS_ERROR;
if ((TREE_CODE (decl) == TYPE_DECL
|| TREE_CODE (decl) == VAR_DECL)
&& !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
gimplify_type_sizes (TREE_TYPE (decl), stmt_p);
if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
{
tree init = DECL_INITIAL (decl);
if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
{
/* This is a variable-sized decl. Simplify its size and mark it
for deferred expansion. Note that mudflap depends on the format
of the emitted code: see mx_register_decls(). */
......@@ -1266,7 +1244,33 @@ gimplify_decl_expr (tree *stmt_p)
/* Indicate that we need to restore the stack level when the
enclosing BIND_EXPR is exited. */
gimplify_ctxp->save_stack = true;
}
}
/* Gimplifies a DECL_EXPR node *STMT_P by making any necessary allocation
and initialization explicit. */
static enum gimplify_status
gimplify_decl_expr (tree *stmt_p)
{
tree stmt = *stmt_p;
tree decl = DECL_EXPR_DECL (stmt);
*stmt_p = NULL_TREE;
if (TREE_TYPE (decl) == error_mark_node)
return GS_ERROR;
if ((TREE_CODE (decl) == TYPE_DECL
|| TREE_CODE (decl) == VAR_DECL)
&& !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
gimplify_type_sizes (TREE_TYPE (decl), stmt_p);
if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
{
tree init = DECL_INITIAL (decl);
if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
gimplify_vla_decl (decl, stmt_p);
if (init && init != error_mark_node)
{
......@@ -4411,7 +4415,14 @@ gimplify_target_expr (tree *expr_p, tree *pre_p, tree *post_p)
if (init)
{
/* TARGET_EXPR temps aren't part of the enclosing block, so add it
to the temps list. */
to the temps list. Handle also variable length TARGET_EXPRs. */
if (TREE_CODE (DECL_SIZE (temp)) != INTEGER_CST)
{
if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
gimplify_type_sizes (TREE_TYPE (temp), pre_p);
gimplify_vla_decl (temp, pre_p);
}
else
gimple_add_tmp_var (temp);
/* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
......
2007-09-20 Jakub Jelinek <jakub@redhat.com>
PR c/33238
PR c/27301
* gcc.c-torture/execute/20070919-1.c: New test.
* gcc.dg/pr33238.c: New test.
* gcc.dg/pr27301.c: New test.
2007-09-20 Richard Sandiford <rsandifo@nildram.co.uk>
* lib/target-supports.exp (check_effective_target_mips64): New
/* PR c/33238 */
typedef __SIZE_TYPE__ size_t;
int memcmp (const void *, const void *, size_t);
void abort (void);
void
__attribute__((noinline))
bar (void *x, void *y)
{
struct S { char w[8]; } *p = x, *q = y;
if (memcmp (p->w, "zyxwvut", 8) != 0)
abort ();
if (memcmp (q[0].w, "abcdefg", 8) != 0)
abort ();
if (memcmp (q[1].w, "ABCDEFG", 8) != 0)
abort ();
if (memcmp (q[2].w, "zyxwvut", 8) != 0)
abort ();
if (memcmp (q[3].w, "zyxwvut", 8) != 0)
abort ();
}
void
__attribute__((noinline))
foo (void *x, int y)
{
struct S { char w[y]; } *p = x, a;
int i;
a = ({ struct S b; b = p[2]; p[3] = b; });
bar (&a, x);
}
int
main (void)
{
struct S { char w[8]; } p[4]
= { "abcdefg", "ABCDEFG", "zyxwvut", "ZYXWVUT" };
foo (p, 8);
return 0;
}
/* PR c/27301 */
/* { dg-do compile } */
/* { dg-options "-O2 -std=gnu89" } */
void
foo (void *ptr, long n)
{
__asm__ __volatile__ ("" :: "m" (({ struct { char x[n]; } *p = ptr; *p; })));
}
void
bar (void *ptr, long n)
{
__asm__ __volatile__ ("" :: "m" (*({ struct { char x[n]; } *p = ptr; p; })));
}
/* PR c/33238 */
/* { dg-do compile } */
/* { dg-options "-std=gnu89" } */
void
reverse (void *x, int y, int z)
{
struct { char w[z]; } *p = x, a;
int i, j;
for (i = y - 1, j = 0; j < y / 2; i--, j++)
({ a = p[i]; p[i] = p[j]; p[j] = a; });
}
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