re PR c/33238 (ICE on statement expression using variable-sized structure in tree_low...
authorJakub Jelinek <jakub@redhat.com>
Thu, 20 Sep 2007 21:19:36 +0000 (23:19 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 20 Sep 2007 21:19:36 +0000 (23:19 +0200)
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

gcc/ChangeLog
gcc/gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20070919-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr27301.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr33238.c [new file with mode: 0644]

index 72df51a9fdf8be6ffb7b42c5d8f804bb1d2f098f..d2f5a59366a1cb396e42519a818e17d5f5e7500b 100644 (file)
@@ -1,3 +1,12 @@
+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.
index d10c8486df87099e0d8e77af835ce87d32fafff6..00a3cf1189a1aab3b493a366eafbfda622a35074 100644 (file)
@@ -1211,6 +1211,41 @@ gimplify_return_expr (tree stmt, tree *pre_p)
   return GS_ALL_DONE;
 }
 
+static void
+gimplify_vla_decl (tree decl, tree *stmt_p)
+{
+  /* 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().  */
+  tree t, addr, ptr_type;
+
+  gimplify_one_sizepos (&DECL_SIZE (decl), stmt_p);
+  gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), stmt_p);
+
+  /* All occurrences of this decl in final gimplified code will be
+     replaced by indirection.  Setting DECL_VALUE_EXPR does two
+     things: First, it lets the rest of the gimplifier know what
+     replacement to use.  Second, it lets the debug info know
+     where to find the value.  */
+  ptr_type = build_pointer_type (TREE_TYPE (decl));
+  addr = create_tmp_var (ptr_type, get_name (decl));
+  DECL_IGNORED_P (addr) = 0;
+  t = build_fold_indirect_ref (addr);
+  SET_DECL_VALUE_EXPR (decl, t);
+  DECL_HAS_VALUE_EXPR_P (decl) = 1;
+
+  t = built_in_decls[BUILT_IN_ALLOCA];
+  t = build_call_expr (t, 1, DECL_SIZE_UNIT (decl));
+  t = fold_convert (ptr_type, t);
+  t = build_gimple_modify_stmt (addr, t);
+
+  gimplify_and_add (t, 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.  */
 
@@ -1235,38 +1270,7 @@ gimplify_decl_expr (tree *stmt_p)
       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().  */
-         tree t, addr, ptr_type;
-
-         gimplify_one_sizepos (&DECL_SIZE (decl), stmt_p);
-         gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), stmt_p);
-
-         /* All occurrences of this decl in final gimplified code will be
-            replaced by indirection.  Setting DECL_VALUE_EXPR does two
-            things: First, it lets the rest of the gimplifier know what
-            replacement to use.  Second, it lets the debug info know
-            where to find the value.  */
-         ptr_type = build_pointer_type (TREE_TYPE (decl));
-         addr = create_tmp_var (ptr_type, get_name (decl));
-         DECL_IGNORED_P (addr) = 0;
-         t = build_fold_indirect_ref (addr);
-         SET_DECL_VALUE_EXPR (decl, t);
-         DECL_HAS_VALUE_EXPR_P (decl) = 1;
-
-         t = built_in_decls[BUILT_IN_ALLOCA];
-         t = build_call_expr (t, 1, DECL_SIZE_UNIT (decl));
-         t = fold_convert (ptr_type, t);
-         t = build_gimple_modify_stmt (addr, t);
-
-         gimplify_and_add (t, stmt_p);
-
-         /* Indicate that we need to restore the stack level when the
-            enclosing BIND_EXPR is exited.  */
-         gimplify_ctxp->save_stack = true;
-       }
+       gimplify_vla_decl (decl, stmt_p);
 
       if (init && init != error_mark_node)
        {
@@ -4411,8 +4415,15 @@ 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.  */
-      gimple_add_tmp_var (temp);
+        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
         expression is supposed to initialize the slot.  */
index d2cf2b0f8138b531a2216d88004a4a87f6708063..675351d8dd30b04b19f073615da748d58823cd76 100644 (file)
@@ -1,3 +1,11 @@
+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
diff --git a/gcc/testsuite/gcc.c-torture/execute/20070919-1.c b/gcc/testsuite/gcc.c-torture/execute/20070919-1.c
new file mode 100644 (file)
index 0000000..ade3d7e
--- /dev/null
@@ -0,0 +1,41 @@
+/* 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;
+}
diff --git a/gcc/testsuite/gcc.dg/pr27301.c b/gcc/testsuite/gcc.dg/pr27301.c
new file mode 100644 (file)
index 0000000..3b5a8f5
--- /dev/null
@@ -0,0 +1,15 @@
+/* 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; })));
+}
diff --git a/gcc/testsuite/gcc.dg/pr33238.c b/gcc/testsuite/gcc.dg/pr33238.c
new file mode 100644 (file)
index 0000000..0b39904
--- /dev/null
@@ -0,0 +1,12 @@
+/* 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; });
+}