OSDN Git Service

Backported from mainline
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 7 May 2014 16:10:35 +0000 (16:10 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 7 May 2014 16:10:35 +0000 (16:10 +0000)
2013-12-03  Jakub Jelinek  <jakub@redhat.com>

PR middle-end/59011
* gimplify.c (nonlocal_vla_vars): New variable.
(gimplify_var_or_parm_decl): Put VAR_DECLs for VLAs into
nonlocal_vla_vars chain.
(gimplify_body): Call declare_vars on nonlocal_vla_vars chain
if outer_bind has DECL_INITIAL (current_function_decl) block.

* gcc.dg/pr59011.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch@210179 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr59011.c [new file with mode: 0644]

index c32f181..c159565 100644 (file)
@@ -1,6 +1,15 @@
 2014-05-07  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       2013-12-03  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/59011
+       * gimplify.c (nonlocal_vla_vars): New variable.
+       (gimplify_var_or_parm_decl): Put VAR_DECLs for VLAs into
+       nonlocal_vla_vars chain.
+       (gimplify_body): Call declare_vars on nonlocal_vla_vars chain
+       if outer_bind has DECL_INITIAL (current_function_decl) block.
+
        2013-11-26  Jakub Jelinek  <jakub@redhat.com>
 
        PR tree-optimization/59014
index 531565e..abb580f 100644 (file)
@@ -1922,6 +1922,9 @@ gimplify_conversion (tree *expr_p)
 /* Nonlocal VLAs seen in the current function.  */
 static struct pointer_set_t *nonlocal_vlas;
 
+/* The VAR_DECLs created for nonlocal VLAs for debug info purposes.  */
+static tree nonlocal_vla_vars;
+
 /* Gimplify a VAR_DECL or PARM_DECL.  Return GS_OK if we expanded a
    DECL_VALUE_EXPR, and it's worth re-examining things.  */
 
@@ -1968,14 +1971,13 @@ gimplify_var_or_parm_decl (tree *expr_p)
            ctx = ctx->outer_context;
          if (!ctx && !pointer_set_insert (nonlocal_vlas, decl))
            {
-             tree copy = copy_node (decl), block;
+             tree copy = copy_node (decl);
 
              lang_hooks.dup_lang_specific_decl (copy);
              SET_DECL_RTL (copy, 0);
              TREE_USED (copy) = 1;
-             block = DECL_INITIAL (current_function_decl);
-             DECL_CHAIN (copy) = BLOCK_VARS (block);
-             BLOCK_VARS (block) = copy;
+             DECL_CHAIN (copy) = nonlocal_vla_vars;
+             nonlocal_vla_vars = copy;
              SET_DECL_VALUE_EXPR (copy, unshare_expr (value_expr));
              DECL_HAS_VALUE_EXPR_P (copy) = 1;
            }
@@ -8057,6 +8059,21 @@ gimplify_body (tree fndecl, bool do_parms)
 
   if (nonlocal_vlas)
     {
+      if (nonlocal_vla_vars)
+       {
+         /* tree-nested.c may later on call declare_vars (..., true);
+            which relies on BLOCK_VARS chain to be the tail of the
+            gimple_bind_vars chain.  Ensure we don't violate that
+            assumption.  */
+         if (gimple_bind_block (outer_bind)
+             == DECL_INITIAL (current_function_decl))
+           declare_vars (nonlocal_vla_vars, outer_bind, true);
+         else
+           BLOCK_VARS (DECL_INITIAL (current_function_decl))
+             = chainon (BLOCK_VARS (DECL_INITIAL (current_function_decl)),
+                        nonlocal_vla_vars);
+         nonlocal_vla_vars = NULL_TREE;
+       }
       pointer_set_destroy (nonlocal_vlas);
       nonlocal_vlas = NULL;
     }
index eeda6f5..f098fe5 100644 (file)
@@ -1,6 +1,11 @@
 2014-05-07  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       2013-12-03  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/59011
+       * gcc.dg/pr59011.c: New test.
+
        2013-11-28  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/59297
diff --git a/gcc/testsuite/gcc.dg/pr59011.c b/gcc/testsuite/gcc.dg/pr59011.c
new file mode 100644 (file)
index 0000000..2fb8187
--- /dev/null
@@ -0,0 +1,22 @@
+/* PR middle-end/59011 */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99" } */
+
+void
+foo (int m)
+{
+  int a[m];
+  void
+  bar (void)
+  {
+    {
+      int
+      baz (void)
+      {
+       return a[0];
+      }
+    }
+    a[0] = 42;
+  }
+  bar ();
+}