From 96ddb7ec9868ac8367a29b3409816f73a8252e1c Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@redhat.com>
Date: Tue, 3 Dec 2013 08:44:37 +0100
Subject: [PATCH] re PR middle-end/59011 (ICE in make_decl_rtl, at
 varasm.c:1147)

	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.

From-SVN: r205621
---
 gcc/ChangeLog                  |  7 +++++++
 gcc/gimplify.c                 | 25 +++++++++++++++++++++----
 gcc/testsuite/ChangeLog        |  3 +++
 gcc/testsuite/gcc.dg/pr59011.c | 22 ++++++++++++++++++++++
 4 files changed, 53 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr59011.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f003eb1ed248..1f006954e4fe 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,12 @@
 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.
+
 	PR target/58864
 	* dojump.c (save_pending_stack_adjust, restore_pending_stack_adjust):
 	New functions.
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 7b9dd5abeebc..2e8c657acf76 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -1689,6 +1689,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.  */
 
@@ -1737,14 +1740,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;
 	    }
@@ -8562,6 +8564,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;
     }
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5b7430605ffe..fe6f94bade38 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
 2013-12-03  Jakub Jelinek  <jakub@redhat.com>
 
+	PR middle-end/59011
+	* gcc.dg/pr59011.c: New test.
+
 	PR target/58864
 	* g++.dg/opt/pr58864.C: New test.
 
diff --git a/gcc/testsuite/gcc.dg/pr59011.c b/gcc/testsuite/gcc.dg/pr59011.c
new file mode 100644
index 000000000000..2fb8187ad552
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr59011.c
@@ -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 ();
+}
-- 
GitLab