From 48eb4e53cdecda5736763287719b422e58c1058f Mon Sep 17 00:00:00 2001
From: Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
Date: Mon, 5 Jul 2004 16:39:15 +0000
Subject: [PATCH] tree.h (DECL_SEEN_IN_BIND_EXPR_P): New macro.

	* tree.h (DECL_SEEN_IN_BIND_EXPR_P): New macro.
	* gimplify.c (gimple_add_tmp_var, gimplify_bind_expr): Use it.
	(gimplify_target_expr, gimplify_expr): Likewise.
	(copy_if_shared_r): No longer need special case for BIND_EXPR.
	(unshare_body, unvisit_body): Only look at nested if BODY_P is
	whole function.
	(gimplify_compound_lval): See if we can strip any useless conversion.
	(gimplify_modify_expr, gimplify_modify_expr_to_memcpy): Take size
	from RHS, not LHS.
	(gimplify_modify_expr_to_memset): Likewise.
	(gimplify_expr, case CONSTRUCTOR): Handle use as statement.
	* tree-inline.c (setup_one_parameter): Use DECL_SEEN_IN_BIND_EXPR_P.
	(declare_inline_vars): Likewise.
	(walk_type_fields): New function.
	(walk_tree): Use it.
	* tree-nested.c (create_tmp_var_for): Show seen in BIND_EXPR.

From-SVN: r84121
---
 gcc/ChangeLog     |  17 ++++
 gcc/gimplify.c    |  79 +++++++++-------
 gcc/tree-inline.c | 228 +++++++++++++++++++++++++---------------------
 gcc/tree-nested.c |   1 +
 gcc/tree.h        |   5 +
 5 files changed, 193 insertions(+), 137 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 791b1837c4a7..8d30f72266a6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -5,6 +5,23 @@
 
 2004-07-05  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
 
+	* tree.h (DECL_SEEN_IN_BIND_EXPR_P): New macro.
+	* gimplify.c (gimple_add_tmp_var, gimplify_bind_expr): Use it.
+	(gimplify_target_expr, gimplify_expr): Likewise.
+	(copy_if_shared_r): No longer need special case for BIND_EXPR.
+	(unshare_body, unvisit_body): Only look at nested if BODY_P is
+	whole function.
+	(gimplify_compound_lval): See if we can strip any useless conversion.
+	(gimplify_modify_expr, gimplify_modify_expr_to_memcpy): Take size
+	from RHS, not LHS.
+	(gimplify_modify_expr_to_memset): Likewise.
+	(gimplify_expr, case CONSTRUCTOR): Handle use as statement.
+	* tree-inline.c (setup_one_parameter): Use DECL_SEEN_IN_BIND_EXPR_P.
+	(declare_inline_vars): Likewise.
+	(walk_type_fields): New function.
+	(walk_tree): Use it.
+	* tree-nested.c (create_tmp_var_for): Show seen in BIND_EXPR.
+	
 	* tree-sra.c (struct sra_walk_fns): Init function now returns bool.
 	(sra_walk_modify_expr): Allow init function to fail.
 	(scan_init): Now returns bool.
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index f6a35bdff00b..20196fecfedf 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -509,20 +509,17 @@ declare_tmp_vars (tree vars, tree scope)
       temps = nreverse (last);
       TREE_CHAIN (last) = BIND_EXPR_VARS (scope);
       BIND_EXPR_VARS (scope) = temps;
-
-      /* We don't add the temps to the block for this BIND_EXPR, as we're
-	 not interested in debugging info for them.  */
     }
 }
 
 void
 gimple_add_tmp_var (tree tmp)
 {
-  if (TREE_CHAIN (tmp) || tmp->decl.seen_in_bind_expr)
+  if (TREE_CHAIN (tmp) || DECL_SEEN_IN_BIND_EXPR_P (tmp))
     abort ();
 
   DECL_CONTEXT (tmp) = current_function_decl;
-  tmp->decl.seen_in_bind_expr = 1;
+  DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
 
   if (gimplify_ctxp)
     {
@@ -657,19 +654,6 @@ copy_if_shared_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
 	TREE_VISITED (t) = 1;
     }
 
-  /* Special-case BIND_EXPR.  We should never be copying these, therefore
-     we can omit examining BIND_EXPR_VARS.  Which also avoids problems with
-     double processing of the DECL_INITIAL, which could be seen via both
-     the BIND_EXPR_VARS and a DECL_EXPR.  */
-  else if (code == BIND_EXPR)
-    {
-      if (TREE_VISITED (t))
-	abort ();
-      TREE_VISITED (t) = 1;
-      *walk_subtrees = 0;
-      walk_tree (&BIND_EXPR_BODY (t), copy_if_shared_r, NULL, NULL);
-    }
-
   /* If this node has been visited already, unshare it and don't look
      any deeper.  */
   else if (TREE_VISITED (t))
@@ -713,8 +697,9 @@ unmark_visited_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
   return NULL_TREE;
 }
 
-/* Unshare all the trees in BODY_P, a pointer to the body of FNDECL, and the
-   bodies of any nested functions.  */
+/* Unshare all the trees in BODY_P, a pointer into the body of FNDECL, and the
+   bodies of any nested functions if we are unsharing the entire body of
+   FNDECL.  */
 
 static void
 unshare_body (tree *body_p, tree fndecl)
@@ -722,8 +707,9 @@ unshare_body (tree *body_p, tree fndecl)
   struct cgraph_node *cgn = cgraph_node (fndecl);
 
   walk_tree (body_p, copy_if_shared_r, NULL, NULL);
-  for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
-    unshare_body (&DECL_SAVED_TREE (cgn->decl), cgn->decl);
+  if (body_p == &DECL_SAVED_TREE (fndecl))
+    for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
+      unshare_body (&DECL_SAVED_TREE (cgn->decl), cgn->decl);
 }
 
 /* Likewise, but mark all trees as not visited.  */
@@ -734,8 +720,9 @@ unvisit_body (tree *body_p, tree fndecl)
   struct cgraph_node *cgn = cgraph_node (fndecl);
 
   walk_tree (body_p, unmark_visited_r, NULL, NULL);
-  for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
-    unvisit_body (&DECL_SAVED_TREE (cgn->decl), cgn->decl);
+  if (body_p == &DECL_SAVED_TREE (fndecl))
+    for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
+      unvisit_body (&DECL_SAVED_TREE (cgn->decl), cgn->decl);
 }
 
 /* Unshare T and all the trees reached from T via TREE_CHAIN.  */
@@ -890,7 +877,7 @@ gimplify_bind_expr (tree *expr_p, tree temp, tree *pre_p)
 
   /* Mark variables seen in this bind expr.  */
   for (t = BIND_EXPR_VARS (bind_expr); t ; t = TREE_CHAIN (t))
-    t->decl.seen_in_bind_expr = 1;
+    DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
 
   gimple_push_bind_expr (bind_expr);
   gimplify_ctxp->save_stack = false;
@@ -1668,7 +1655,8 @@ gimplify_compound_lval (tree *expr_p, tree *pre_p,
   tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval, fallback);
   ret = MIN (ret, tret);
 
-  /* And finally, the indices and operands to BIT_FIELD_REF.  */
+  /* And finally, the indices and operands to BIT_FIELD_REF.  During this
+     loop we also remove any useless conversions.  */
   for (; VARRAY_ACTIVE_SIZE (stack) > 0; )
     {
       tree t = VARRAY_TOP_TREE (stack);
@@ -1700,7 +1688,9 @@ gimplify_compound_lval (tree *expr_p, tree *pre_p,
 				is_gimple_val, fb_rvalue);
 	  ret = MIN (ret, tret);
 	}
-	  
+
+      STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
+
       /* The innermost expression P may have originally had TREE_SIDE_EFFECTS
 	 set which would have caused all the outer expressions in EXPR_P
 	 leading to P to also have had TREE_SIDE_EFFECTS set.  */
@@ -2321,7 +2311,7 @@ gimplify_modify_expr_to_memcpy (tree *expr_p, bool want_value)
   to = TREE_OPERAND (*expr_p, 0);
   from = TREE_OPERAND (*expr_p, 1);
 
-  t = TYPE_SIZE_UNIT (TREE_TYPE (to));
+  t = TYPE_SIZE_UNIT (TREE_TYPE (from));
   t = unshare_expr (t);
   t = SUBSTITUTE_PLACEHOLDER_IN_EXPR (t, to);
   t = SUBSTITUTE_PLACEHOLDER_IN_EXPR (t, from);
@@ -2356,7 +2346,7 @@ gimplify_modify_expr_to_memset (tree *expr_p, bool want_value)
 
   to = TREE_OPERAND (*expr_p, 0);
 
-  t = TYPE_SIZE_UNIT (TREE_TYPE (to));
+  t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_OPERAND (*expr_p, 1)));
   t = unshare_expr (t);
   t = SUBSTITUTE_PLACEHOLDER_IN_EXPR (t, to);
   args = tree_cons (NULL, t, NULL);
@@ -2772,8 +2762,15 @@ gimplify_modify_expr (tree *expr_p, tree *pre_p, tree *post_p, bool want_value)
   /* If the value being copied is of variable width, expose the length
      if the copy by converting the whole thing to a memcpy/memset.
      Note that we need to do this before gimplifying any of the operands
-     so that we can resolve any PLACEHOLDER_EXPRs in the size.  */
-  if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p))) != INTEGER_CST)
+     so that we can resolve any PLACEHOLDER_EXPRs in the size. 
+     Also note that the RTL expander uses the size of the expression to
+     be copied, not of the destination, so that is what we must here.
+     The types on both sides of the MODIFY_EXPR should be the same,
+     but they aren't always and there are problems with class-wide types
+     in Ada where it's hard to make it "correct".  */
+  if (TREE_CODE (TREE_TYPE (*from_p)) != ERROR_MARK
+      && TYPE_SIZE_UNIT (TREE_TYPE (*from_p))
+      && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*from_p))) != INTEGER_CST)
     {
       if (TREE_CODE (*from_p) == CONSTRUCTOR)
 	return gimplify_modify_expr_to_memset (expr_p, want_value);
@@ -3361,7 +3358,7 @@ gimplify_target_expr (tree *expr_p, tree *pre_p, tree *post_p)
       TREE_OPERAND (targ, 3) = init;
       TARGET_EXPR_INITIAL (targ) = NULL_TREE;
     }
-  else if (!temp->decl.seen_in_bind_expr)
+  else if (!DECL_SEEN_IN_BIND_EXPR_P (temp))
     /* We should have expanded this before.  */
     abort ();
 
@@ -3699,8 +3696,20 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
 	  break;
 
 	case CONSTRUCTOR:
-	  /* Don't reduce this in place; let gimplify_init_constructor work
-	     its magic.  */
+	  /* Don't reduce this in place; let gimplify_init_constructor work its
+	     magic.  Buf if we're just elaborating this for side effects, just
+	     gimplify any element that has side-effects.  */
+	  if (fallback == fb_none)
+	    {
+	      for (tmp = CONSTRUCTOR_ELTS (*expr_p); tmp;
+		   tmp = TREE_CHAIN (tmp))
+		if (TREE_SIDE_EFFECTS (TREE_VALUE (tmp)))
+		  gimplify_expr (&TREE_VALUE (tmp), pre_p, post_p,
+				 gimple_test_f, fallback);
+
+	      *expr_p = NULL_TREE;
+	    }
+		  
 	  ret = GS_ALL_DONE;
 	  break;
 
@@ -3801,7 +3810,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
 	  tmp = *expr_p;
 	  if (!TREE_STATIC (tmp) && !DECL_EXTERNAL (tmp)
 	      && decl_function_context (tmp) == current_function_decl
-	      && !tmp->decl.seen_in_bind_expr)
+	      && !DECL_SEEN_IN_BIND_EXPR_P (tmp))
 	    {
 #ifdef ENABLE_CHECKING
 	      if (!errorcount && !sorrycount)
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 15fb9282e72f..34a158c20f66 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -766,7 +766,7 @@ setup_one_parameter (inline_data *id, tree p, tree value, tree fn,
   *vars = var;
 
   /* Make gimplifier happy about this variable.  */
-  var->decl.seen_in_bind_expr = lang_hooks.gimple_before_inlining;
+  DECL_SEEN_IN_BIND_EXPR_P (var) = lang_hooks.gimple_before_inlining;
 
   /* Even if P was TREE_READONLY, the new VAR should not be.
      In the original code, we would have constructed a
@@ -1951,6 +1951,100 @@ save_body (tree fn, tree *arg_copy)
   return body;
 }
 
+#define WALK_SUBTREE(NODE)				\
+  do							\
+    {							\
+      result = walk_tree (&(NODE), func, data, htab);	\
+      if (result)					\
+	return result;					\
+    }							\
+  while (0)
+
+/* This is a subroutine of walk_tree that walks field of TYPE that are to
+   be walked whenever a type is seen in the tree.  Rest of operands and return
+   value are as for walk_tree.  */
+
+static tree
+walk_type_fields (tree type, walk_tree_fn func, void *data, void *htab)
+{
+  tree result = NULL_TREE;
+
+  switch (TREE_CODE (type))
+    {
+    case POINTER_TYPE:
+    case REFERENCE_TYPE:
+      /* We have to worry about mutually recursive pointers.  These can't
+	 be written in C.  They can in Ada.  It's pathlogical, but
+	 there's an ACATS test (c38102a) that checks it.  Deal with this
+	 by checking if we're pointing to another pointer, that one
+	 points to another pointer, that one does too, and we have no htab.
+	 If so, get a hash table.  We check three levels deep to avoid
+	 the cost of the hash table if we don't need one.  */
+      if (POINTER_TYPE_P (TREE_TYPE (type))
+	  && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (type)))
+	  && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (TREE_TYPE (type))))
+	  && !htab)
+	{
+	  result = walk_tree_without_duplicates (&TREE_TYPE (type),
+						 func, data);
+	  if (result)
+	    return result;
+
+	  break;
+	}
+
+      /* ... fall through ... */
+
+    case COMPLEX_TYPE:
+      WALK_SUBTREE (TREE_TYPE (type));
+      break;
+
+    case METHOD_TYPE:
+      WALK_SUBTREE (TYPE_METHOD_BASETYPE (type));
+
+      /* Fall through.  */
+
+    case FUNCTION_TYPE:
+      WALK_SUBTREE (TREE_TYPE (type));
+      {
+	tree arg;
+
+	/* We never want to walk into default arguments.  */
+	for (arg = TYPE_ARG_TYPES (type); arg; arg = TREE_CHAIN (arg))
+	  WALK_SUBTREE (TREE_VALUE (arg));
+      }
+      break;
+
+    case ARRAY_TYPE:
+      /* Don't follow this nodes's type if a pointer for fear that we'll
+	 have infinite recursion.  Those types are uninteresting anyway. */
+      if (!POINTER_TYPE_P (TREE_TYPE (type))
+	  && TREE_CODE (TREE_TYPE (type)) != OFFSET_TYPE)
+	WALK_SUBTREE (TREE_TYPE (type));
+      WALK_SUBTREE (TYPE_DOMAIN (type));
+      break;
+
+    case BOOLEAN_TYPE:
+    case ENUMERAL_TYPE:
+    case INTEGER_TYPE:
+    case CHAR_TYPE:
+    case REAL_TYPE:
+      WALK_SUBTREE (TYPE_MIN_VALUE (type));
+      WALK_SUBTREE (TYPE_MAX_VALUE (type));
+      break;
+
+    case OFFSET_TYPE:
+      WALK_SUBTREE (TREE_TYPE (type));
+      WALK_SUBTREE (TYPE_OFFSET_BASETYPE (type));
+      break;
+
+    default:
+      break;
+    }
+
+  return NULL_TREE;
+}
+
 /* Apply FUNC to all the sub-trees of TP in a pre-order traversal.  FUNC is
    called with the DATA and the address of each sub-tree.  If FUNC returns a
    non-NULL value, the traversal is aborted, and the value returned by FUNC
@@ -1965,15 +2059,6 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
   int walk_subtrees;
   tree result;
 
-#define WALK_SUBTREE(NODE)				\
-  do							\
-    {							\
-      result = walk_tree (&(NODE), func, data, htab);	\
-      if (result)					\
-	return result;					\
-    }							\
-  while (0)
-
 #define WALK_SUBTREE_TAIL(NODE)				\
   do							\
     {							\
@@ -2025,43 +2110,42 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
   if (result || ! walk_subtrees)
     return result;
 
-  /* If this is a DECL_EXPR, walk into various fields of the type or variable
-     that it's defining.  We only want to walk into these fields of a decl
-     or type in this case.
+  /* If this is a DECL_EXPR, walk into various fields of the type that it's
+     defining.  We only want to walk into these fields of a type in this
+     case.  Note that decls get walked as part of the processing of a
+     BIND_EXPR.
 
      ??? Precisely which fields of types that we are supposed to walk in
      this case vs. the normal case aren't well defined.  */
   if (code == DECL_EXPR
-      && TREE_CODE (DECL_EXPR_DECL (*tp)) != ERROR_MARK
+      && TREE_CODE (DECL_EXPR_DECL (*tp)) == TYPE_DECL
       && TREE_CODE (TREE_TYPE (DECL_EXPR_DECL (*tp))) != ERROR_MARK)
     {
-      tree decl = DECL_EXPR_DECL (*tp);
-      tree type = TREE_TYPE (decl);
+      tree *type_p = &TREE_TYPE (DECL_EXPR_DECL (*tp));
 
-      /* Walk into fields of the DECL if it's not a type.  */
-      if (TREE_CODE (decl) != TYPE_DECL)
-	{
-	  if (TREE_CODE (decl) != FIELD_DECL && TREE_CODE (decl) != PARM_DECL)
-	    WALK_SUBTREE (DECL_INITIAL (decl));
+      /* Call the function for the type.  See if it returns anything or
+	 doesn't want us to continue.  If we are to continue, walk both
+	 the normal fields and those for the declaration case.  */
+      result = (*func) (type_p, &walk_subtrees, data);
+      if (result || !walk_subtrees)
+	return NULL_TREE;
 
-	  WALK_SUBTREE (DECL_SIZE (decl));
-	  WALK_SUBTREE_TAIL (DECL_SIZE_UNIT (decl));
-	}
+      result = walk_type_fields (*type_p, func, data, htab_);
+      if (result)
+	return result;
 
-      /* Otherwise, we are declaring a type.  First do the common fields via
-	 recursion, then the fields we only do when we are declaring the type
-	 or object.  */
-      WALK_SUBTREE (type);
-      WALK_SUBTREE (TYPE_SIZE (type));
-      WALK_SUBTREE (TYPE_SIZE_UNIT (type));
+      WALK_SUBTREE (TYPE_SIZE (*type_p));
+      WALK_SUBTREE (TYPE_SIZE_UNIT (*type_p));
 
       /* If this is a record type, also walk the fields.  */
-      if (TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE
-	  || TREE_CODE (type) == QUAL_UNION_TYPE)
+      if (TREE_CODE (*type_p) == RECORD_TYPE
+	  || TREE_CODE (*type_p) == UNION_TYPE
+	  || TREE_CODE (*type_p) == QUAL_UNION_TYPE)
 	{
 	  tree field;
 
-	  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+	  for (field = TYPE_FIELDS (*type_p); field;
+	       field = TREE_CHAIN (field))
 	    {
 	      /* We'd like to look at the type of the field, but we can easily
 		 get infinite recursion.  So assume it's pointed to elsewhere
@@ -2072,7 +2156,7 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
 	      WALK_SUBTREE (DECL_FIELD_OFFSET (field));
 	      WALK_SUBTREE (DECL_SIZE (field));
 	      WALK_SUBTREE (DECL_SIZE_UNIT (field));
-	      if (TREE_CODE (type) == QUAL_UNION_TYPE)
+	      if (TREE_CODE (*type_p) == QUAL_UNION_TYPE)
 		WALK_SUBTREE (DECL_QUALIFIER (field));
 	    }
 	}
@@ -2114,6 +2198,13 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
 #endif
     }
 
+  /* If this is a type, walk the needed fields in the type.  */
+  else if (TYPE_P (*tp))
+    {
+      result = walk_type_fields (*tp, func, data, htab_);
+      if (result)
+	return result;
+    }
   else
     {
       /* Not one of the easy cases.  We must explicitly go through the
@@ -2126,8 +2217,6 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
 	case REAL_CST:
 	case VECTOR_CST:
 	case STRING_CST:
-	case VECTOR_TYPE:
-	case VOID_TYPE:
 	case BLOCK:
 	case PLACEHOLDER_EXPR:
 	case SSA_NAME:
@@ -2183,7 +2272,6 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
 		WALK_SUBTREE (DECL_INITIAL (decl));
 		WALK_SUBTREE (DECL_SIZE (decl));
 		WALK_SUBTREE (DECL_SIZE_UNIT (decl));
-		WALK_SUBTREE (TREE_TYPE (decl));
 	      }
 	    WALK_SUBTREE_TAIL (BIND_EXPR_BODY (*tp));
 	  }
@@ -2196,70 +2284,6 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
 	  }
 	  break;
 
-	case POINTER_TYPE:
-	case REFERENCE_TYPE:
-	  /* We have to worry about mutually recursive pointers.  These can't
-	     be written in C.  They can in Ada.  It's pathlogical, but
-	     there's an ACATS test (c38102a) that checks it.  Deal with this
-	     by checking if we're pointing to another pointer, that one
-	     points to another pointer, that one does too, and we have no htab.
-	     If so, get a hash table.  We check three levels deep to avoid
-	     the cost of the hash table if we don't need one.  */
-	  if (POINTER_TYPE_P (TREE_TYPE (*tp))
-	      && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (*tp)))
-	      && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (TREE_TYPE (*tp))))
-	      && !htab)
-	    {
-	      result = walk_tree_without_duplicates (&TREE_TYPE (*tp),
-						     func, data);
-	      if (result)
-		return result;
-
-	      break;
-	    }
-
-	  /* ... fall through ... */
-
-	case COMPLEX_TYPE:
-	  WALK_SUBTREE_TAIL (TREE_TYPE (*tp));
-	  break;
-
-	case METHOD_TYPE:
-	  WALK_SUBTREE (TYPE_METHOD_BASETYPE (*tp));
-
-	  /* Fall through.  */
-
-	case FUNCTION_TYPE:
-	  WALK_SUBTREE (TREE_TYPE (*tp));
-	  {
-	    tree arg;
-
-	    /* We never want to walk into default arguments.  */
-	    for (arg = TYPE_ARG_TYPES (*tp); arg; arg = TREE_CHAIN (arg))
-	      WALK_SUBTREE (TREE_VALUE (arg));
-	  }
-	  break;
-
-	case ARRAY_TYPE:
-	  /* Don't follow this nodes's type if a pointer for fear that we'll
-	     have infinite recursion.  Those types are uninteresting anyway. */
-	  if (!POINTER_TYPE_P (TREE_TYPE (*tp))
-	      && TREE_CODE (TREE_TYPE (*tp)) != OFFSET_TYPE)
-	    WALK_SUBTREE (TREE_TYPE (*tp));
-	  WALK_SUBTREE_TAIL (TYPE_DOMAIN (*tp));
-
-	case BOOLEAN_TYPE:
-	case ENUMERAL_TYPE:
-	case INTEGER_TYPE:
-	case CHAR_TYPE:
-	case REAL_TYPE:
-	  WALK_SUBTREE (TYPE_MIN_VALUE (*tp));
-	  WALK_SUBTREE_TAIL (TYPE_MAX_VALUE (*tp));
-
-	case OFFSET_TYPE:
-	  WALK_SUBTREE (TREE_TYPE (*tp));
-	  WALK_SUBTREE_TAIL (TYPE_OFFSET_BASETYPE (*tp));
-
 	default:
 	  /* ??? This could be a language-defined node.  We really should make
 	     a hook for it, but right now just ignore it.  */
@@ -2498,7 +2522,7 @@ declare_inline_vars (tree bind_expr, tree vars)
       tree t;
 
       for (t = vars; t; t = TREE_CHAIN (t))
-	vars->decl.seen_in_bind_expr = 1;
+	DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
     }
 
   add_var_to_bind_expr (bind_expr, vars);
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index 668861c15b96..fdcaaf82436e 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -145,6 +145,7 @@ create_tmp_var_for (struct nesting_info *info, tree type, const char *prefix)
   tmp_var = create_tmp_var_raw (type, prefix);
   DECL_CONTEXT (tmp_var) = info->context;
   TREE_CHAIN (tmp_var) = info->new_local_var_chain;
+  DECL_SEEN_IN_BIND_EXPR_P (tmp_var) = 1;
   info->new_local_var_chain = tmp_var;
 
   return tmp_var;
diff --git a/gcc/tree.h b/gcc/tree.h
index fc854d5c616a..f093f7999873 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1985,6 +1985,11 @@ extern GTY (()) unsigned binfo_lang_slots;
 #define DECL_DECLARED_INLINE_P(NODE) \
   (FUNCTION_DECL_CHECK (NODE)->decl.declared_inline_flag)
 
+/* Nonzero in a decl means that the gimplifier has seen (or placed)
+   this variable in a BIND_EXPR.  */
+#define DECL_SEEN_IN_BIND_EXPR_P(NODE) \
+  (DECL_CHECK (NODE)->decl.seen_in_bind_expr)
+
 /* In a VAR_DECL, nonzero if the decl is a register variable with
    an explicit asm specification.  */
 #define DECL_HARD_REGISTER(NODE)  (DECL_CHECK (NODE)->decl.inline_flag)
-- 
GitLab