diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c5f37aa2356353cadd43d583b0e0516aa1202816..ef35c991c54a06d731837bb3cd465b86d49bb929 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,19 @@
+2006-06-13  Eric Botcazou  <ebotcazou@adacore.com>
+
+	PR debug/26754
+	* gimplify.c (declare_tmp_vars): Rename into declare_vars.
+	Add debug_info parameter.  Chain the vars to the BLOCK instead
+	of the BIND_EXPR if debug info are requested for them.
+	(pop_gimplify_context): Adjust for above change.
+	(gimple_add_tmp_var): Likewise.
+	* tree-gimple.h (declare_tmp_vars): Rename into declare_vars.
+	Add bool parameter.
+	* tree-nested.c (convert_nonlocal_reference): Adjust for above change.
+	(convert_local_reference): Likewise.
+	(get_local_debug_decl): Set DECL_IGNORED_P on the original variable.
+	(finalize_nesting_tree_1): Request that debug info be emitted
+	for debug_var_chain.
+
 2006-06-13  Maxim Kuvyrkov  <mkuvyrkov@ispras.ru>
 
 	* haifa-sched.c (unlink_other_notes, unlink_line_notes): Fix the patch
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 17fc560fd30e7d7d2efd651123b92def28e72d7b..08c5caa63d9f3d3c8fb17bc6d08244258d7bb5c0 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -180,7 +180,7 @@ pop_gimplify_context (tree body)
     DECL_GIMPLE_FORMAL_TEMP_P (t) = 0;
 
   if (body)
-    declare_tmp_vars (c->temps, body);
+    declare_vars (c->temps, body, false);
   else
     record_vars (c->temps);
 
@@ -645,15 +645,16 @@ get_initialized_tmp_var (tree val, tree *pre_p, tree *post_p)
   return internal_get_tmp_var (val, pre_p, post_p, false);
 }
 
-/* Declares all the variables in VARS in SCOPE.  */
+/* Declares all the variables in VARS in SCOPE.  If DEBUG_INFO is
+   true, generate debug info for them; otherwise don't.  */
 
 void
-declare_tmp_vars (tree vars, tree scope)
+declare_vars (tree vars, tree scope, bool debug_info)
 {
   tree last = vars;
   if (last)
     {
-      tree temps;
+      tree temps, block;
 
       /* C99 mode puts the default 'return 0;' for main outside the outer
 	 braces.  So drill down until we find an actual scope.  */
@@ -663,8 +664,27 @@ declare_tmp_vars (tree vars, tree scope)
       gcc_assert (TREE_CODE (scope) == BIND_EXPR);
 
       temps = nreverse (last);
-      TREE_CHAIN (last) = BIND_EXPR_VARS (scope);
-      BIND_EXPR_VARS (scope) = temps;
+
+      block = BIND_EXPR_BLOCK (scope);
+      if (!block || !debug_info)
+	{
+	  TREE_CHAIN (last) = BIND_EXPR_VARS (scope);
+	  BIND_EXPR_VARS (scope) = temps;
+	}
+      else
+	{
+	  /* We need to attach the nodes both to the BIND_EXPR and to its
+	     associated BLOCK for debugging purposes.  The key point here
+	     is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR
+	     is a subchain of the BIND_EXPR_VARS of the BIND_EXPR.  */
+	  if (BLOCK_VARS (block))
+	    BLOCK_VARS (block) = chainon (BLOCK_VARS (block), temps);
+	  else
+	    {
+	      BIND_EXPR_VARS (scope) = chainon (BIND_EXPR_VARS (scope), temps);
+	      BLOCK_VARS (block) = temps;
+	    }
+	}
     }
 }
 
@@ -694,7 +714,7 @@ gimple_add_tmp_var (tree tmp)
   else if (cfun)
     record_vars (tmp);
   else
-    declare_tmp_vars (tmp, DECL_SAVED_TREE (current_function_decl));
+    declare_vars (tmp, DECL_SAVED_TREE (current_function_decl), false);
 }
 
 /* Determines whether to assign a locus to the statement STMT.  */
diff --git a/gcc/tree-gimple.h b/gcc/tree-gimple.h
index 9cba07f55975559190d96078ee200c83de0278d6..60fde4ec9ff69bd5b1324c2fa34d9bbeffdc150a 100644
--- a/gcc/tree-gimple.h
+++ b/gcc/tree-gimple.h
@@ -30,7 +30,8 @@ extern tree create_tmp_var_name (const char *);
 extern tree create_tmp_var (tree, const char *);
 extern tree get_initialized_tmp_var (tree, tree *, tree *);
 extern tree get_formal_tmp_var (tree, tree *);
-extern void declare_tmp_vars (tree, tree);
+
+extern void declare_vars (tree, tree, bool);
 
 extern void annotate_all_with_locus (tree *, location_t);
 
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index 886681983ee49eb1aa40e3f87b3ae6ffe829be5b..67a13c28a99a862dfd50186ea8d617c698da2d21 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -1048,7 +1048,7 @@ convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data)
       walk_body (convert_nonlocal_reference, info, &OMP_PARALLEL_BODY (t));
 
       if (info->new_local_var_chain)
-	declare_tmp_vars (info->new_local_var_chain, OMP_PARALLEL_BODY (t));
+	declare_vars (info->new_local_var_chain, OMP_PARALLEL_BODY (t), false);
       info->new_local_var_chain = save_local_var_chain;
       info->suppress_expansion = save_suppress;
       break;
@@ -1186,6 +1186,9 @@ get_local_debug_decl (struct nesting_info *info, tree decl, tree field)
   TREE_CHAIN (new_decl) = info->debug_var_chain;
   info->debug_var_chain = new_decl;
 
+  /* Do not emit debug info twice.  */
+  DECL_IGNORED_P (decl) = 1;
+
   return new_decl;
 }
 
@@ -1331,7 +1334,7 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data)
       walk_body (convert_local_reference, info, &OMP_PARALLEL_BODY (t));
 
       if (info->new_local_var_chain)
-	declare_tmp_vars (info->new_local_var_chain, OMP_PARALLEL_BODY (t));
+	declare_vars (info->new_local_var_chain, OMP_PARALLEL_BODY (t), false);
       info->new_local_var_chain = save_local_var_chain;
       info->suppress_expansion = save_suppress;
       break;
@@ -1804,11 +1807,11 @@ finalize_nesting_tree_1 (struct nesting_info *root)
   /* Make sure all new local variables get inserted into the
      proper BIND_EXPR.  */
   if (root->new_local_var_chain)
-    declare_tmp_vars (root->new_local_var_chain,
-		      DECL_SAVED_TREE (root->context));
+    declare_vars (root->new_local_var_chain, DECL_SAVED_TREE (root->context),
+		  false);
   if (root->debug_var_chain)
-    declare_tmp_vars (root->debug_var_chain,
-		      DECL_SAVED_TREE (root->context));
+    declare_vars (root->debug_var_chain, DECL_SAVED_TREE (root->context),
+		  true);
 
   /* Dump the translated tree function.  */
   dump_function (TDI_nested, root->context);