This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix a series of bugs in gimplify.c and tree-inline.c


These changes depend on each other and fix a series of bugs that occurred in
the ACATS test suite.  The bulk of this change is moving code around
in walk_tree.

First, a CONSTRUCTOR with TREE_SIDE_EFFECTS can be a statement (ac3207a) and
we weren't handling it correctly.

The RTL expander takes the size of a MODIFY_EXPR from the rhs, so the
gimplifier should look there to see if it's a variable-sized move.  Yes, the
tree types of both sides of a MODIFY_EXPR should be the same, but they aren't
in some cases and in at least one case (c390004) can't be.  But even if that
can be fixed, it's best to be consistent between the gimplifier and RTL
expander.

If the nesting lowering processor creates a temporary, it should be marked as
being in a BIND_EXPR because it's going to be placed there (c37213b).  Also,
we should have an accessor macro for seen_in_bind_expr.

Then were more sharing-related problems (c32107a & c380004).  We have a real
mess as to what's supposed to be processed by virtue of a decl or type being
in BIND_VARS or in a DECL_EXPR by both the tree walker and the gimplifier.
It's still a mess, but at least it's now a *little* more consistent between
the two and fixes a few bugs.

Tested on x64_64-linux-gnu.

There are now just three remaining sets of problems that cause ICEs on the
ACATS.  Those fixes will be my next batch of changes and then come the code
generation correctness issues.

2004-07-05  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>

	* tree.h (DECL_SEEN_IN_BIND_EXPR_P): New macro.
	* gimple.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.
	
*** gimplify.c	3 Jul 2004 13:51:51 -0000	2.40
--- gimplify.c	5 Jul 2004 16:26:10 -0000
*************** declare_tmp_vars (tree vars, tree scope)
*** 510,516 ****
        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.  */
      }
  }
--- 510,513 ----
*************** void
*** 519,527 ****
  gimple_add_tmp_var (tree tmp)
  {
!   if (TREE_CHAIN (tmp) || tmp->decl.seen_in_bind_expr)
      abort ();
  
    DECL_CONTEXT (tmp) = current_function_decl;
!   tmp->decl.seen_in_bind_expr = 1;
  
    if (gimplify_ctxp)
--- 516,524 ----
  gimple_add_tmp_var (tree tmp)
  {
!   if (TREE_CHAIN (tmp) || DECL_SEEN_IN_BIND_EXPR_P (tmp))
      abort ();
  
    DECL_CONTEXT (tmp) = current_function_decl;
!   DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
  
    if (gimplify_ctxp)
*************** copy_if_shared_r (tree *tp, int *walk_su
*** 658,674 ****
      }
  
-   /* 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.  */
--- 655,658 ----
*************** unmark_visited_r (tree *tp, int *walk_su
*** 714,719 ****
  }
  
! /* Unshare all the trees in BODY_P, a pointer to the body of FNDECL, and the
!    bodies of any nested functions.  */
  
  static void
--- 698,704 ----
  }
  
! /* 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)
*** 723,728 ****
  
    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);
  }
  
--- 708,714 ----
  
    walk_tree (body_p, copy_if_shared_r, NULL, NULL);
!   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);
  }
  
*************** unvisit_body (tree *body_p, tree fndecl)
*** 735,740 ****
  
    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);
  }
  
--- 721,727 ----
  
    walk_tree (body_p, unmark_visited_r, NULL, NULL);
!   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);
  }
  
*************** gimplify_bind_expr (tree *expr_p, tree t
*** 891,895 ****
    /* 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;
  
    gimple_push_bind_expr (bind_expr);
--- 878,882 ----
    /* Mark variables seen in this bind expr.  */
    for (t = BIND_EXPR_VARS (bind_expr); t ; t = TREE_CHAIN (t))
!     DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
  
    gimple_push_bind_expr (bind_expr);
*************** gimplify_compound_lval (tree *expr_p, tr
*** 1669,1673 ****
    ret = MIN (ret, tret);
  
!   /* And finally, the indices and operands to BIT_FIELD_REF.  */
    for (; VARRAY_ACTIVE_SIZE (stack) > 0; )
      {
--- 1656,1661 ----
    ret = MIN (ret, tret);
  
!   /* 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; )
      {
*************** gimplify_compound_lval (tree *expr_p, tr
*** 1701,1705 ****
  	  ret = MIN (ret, tret);
  	}
! 	  
        /* The innermost expression P may have originally had TREE_SIDE_EFFECTS
  	 set which would have caused all the outer expressions in EXPR_P
--- 1689,1695 ----
  	  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
*************** gimplify_modify_expr_to_memcpy (tree *ex
*** 2322,2326 ****
    from = TREE_OPERAND (*expr_p, 1);
  
!   t = TYPE_SIZE_UNIT (TREE_TYPE (to));
    t = unshare_expr (t);
    t = SUBSTITUTE_PLACEHOLDER_IN_EXPR (t, to);
--- 2312,2316 ----
    from = TREE_OPERAND (*expr_p, 1);
  
!   t = TYPE_SIZE_UNIT (TREE_TYPE (from));
    t = unshare_expr (t);
    t = SUBSTITUTE_PLACEHOLDER_IN_EXPR (t, to);
*************** gimplify_modify_expr_to_memset (tree *ex
*** 2357,2361 ****
    to = TREE_OPERAND (*expr_p, 0);
  
!   t = TYPE_SIZE_UNIT (TREE_TYPE (to));
    t = unshare_expr (t);
    t = SUBSTITUTE_PLACEHOLDER_IN_EXPR (t, to);
--- 2347,2351 ----
    to = TREE_OPERAND (*expr_p, 0);
  
!   t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_OPERAND (*expr_p, 1)));
    t = unshare_expr (t);
    t = SUBSTITUTE_PLACEHOLDER_IN_EXPR (t, to);
*************** gimplify_modify_expr (tree *expr_p, tree
*** 2773,2778 ****
       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)
      {
        if (TREE_CODE (*from_p) == CONSTRUCTOR)
--- 2763,2775 ----
       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. 
!      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)
*************** gimplify_target_expr (tree *expr_p, tree
*** 3362,3366 ****
        TARGET_EXPR_INITIAL (targ) = NULL_TREE;
      }
!   else if (!temp->decl.seen_in_bind_expr)
      /* We should have expanded this before.  */
      abort ();
--- 3359,3363 ----
        TARGET_EXPR_INITIAL (targ) = NULL_TREE;
      }
!   else if (!DECL_SEEN_IN_BIND_EXPR_P (temp))
      /* We should have expanded this before.  */
      abort ();
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 3700,3705 ****
  
  	case CONSTRUCTOR:
! 	  /* Don't reduce this in place; let gimplify_init_constructor work
! 	     its magic.  */
  	  ret = GS_ALL_DONE;
  	  break;
--- 3697,3714 ----
  
  	case CONSTRUCTOR:
! 	  /* 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;
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 3802,3806 ****
  	  if (!TREE_STATIC (tmp) && !DECL_EXTERNAL (tmp)
  	      && decl_function_context (tmp) == current_function_decl
! 	      && !tmp->decl.seen_in_bind_expr)
  	    {
  #ifdef ENABLE_CHECKING
--- 3811,3815 ----
  	  if (!TREE_STATIC (tmp) && !DECL_EXTERNAL (tmp)
  	      && decl_function_context (tmp) == current_function_decl
! 	      && !DECL_SEEN_IN_BIND_EXPR_P (tmp))
  	    {
  #ifdef ENABLE_CHECKING
*** tree-inline.c	3 Jul 2004 14:48:14 -0000	1.120
--- tree-inline.c	5 Jul 2004 13:34:18 -0000
*************** setup_one_parameter (inline_data *id, tr
*** 767,771 ****
  
    /* Make gimplifier happy about this variable.  */
!   var->decl.seen_in_bind_expr = lang_hooks.gimple_before_inlining;
  
    /* Even if P was TREE_READONLY, the new VAR should not be.
--- 767,771 ----
  
    /* Make gimplifier happy about this variable.  */
!   DECL_SEEN_IN_BIND_EXPR_P (var) = lang_hooks.gimple_before_inlining;
  
    /* Even if P was TREE_READONLY, the new VAR should not be.
*************** save_body (tree fn, tree *arg_copy)
*** 1952,1955 ****
--- 1952,2049 ----
  }
  
+ #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
*************** walk_tree (tree *tp, walk_tree_fn func, 
*** 1966,1978 ****
    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							\
--- 2060,2063 ----
*************** walk_tree (tree *tp, walk_tree_fn func, 
*** 2026,2066 ****
      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.
  
       ??? 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 (TREE_TYPE (DECL_EXPR_DECL (*tp))) != ERROR_MARK)
      {
!       tree decl = DECL_EXPR_DECL (*tp);
!       tree type = TREE_TYPE (decl);
  
!       /* 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));
  
! 	  WALK_SUBTREE (DECL_SIZE (decl));
! 	  WALK_SUBTREE_TAIL (DECL_SIZE_UNIT (decl));
! 	}
  
!       /* 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));
  
        /* 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)
  	{
  	  tree field;
  
! 	  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
  	    {
  	      /* We'd like to look at the type of the field, but we can easily
--- 2111,2150 ----
      return result;
  
!   /* 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)) == TYPE_DECL
        && TREE_CODE (TREE_TYPE (DECL_EXPR_DECL (*tp))) != ERROR_MARK)
      {
!       tree *type_p = &TREE_TYPE (DECL_EXPR_DECL (*tp));
  
!       /* 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;
  
!       result = walk_type_fields (*type_p, func, data, htab_);
!       if (result)
! 	return result;
  
!       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_p) == RECORD_TYPE
! 	  || TREE_CODE (*type_p) == UNION_TYPE
! 	  || TREE_CODE (*type_p) == QUAL_UNION_TYPE)
  	{
  	  tree 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
*************** walk_tree (tree *tp, walk_tree_fn func, 
*** 2073,2077 ****
  	      WALK_SUBTREE (DECL_SIZE (field));
  	      WALK_SUBTREE (DECL_SIZE_UNIT (field));
! 	      if (TREE_CODE (type) == QUAL_UNION_TYPE)
  		WALK_SUBTREE (DECL_QUALIFIER (field));
  	    }
--- 2157,2161 ----
  	      WALK_SUBTREE (DECL_SIZE (field));
  	      WALK_SUBTREE (DECL_SIZE_UNIT (field));
! 	      if (TREE_CODE (*type_p) == QUAL_UNION_TYPE)
  		WALK_SUBTREE (DECL_QUALIFIER (field));
  	    }
*************** walk_tree (tree *tp, walk_tree_fn func, 
*** 2115,2118 ****
--- 2199,2209 ----
      }
  
+   /* 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
      {
*************** walk_tree (tree *tp, walk_tree_fn func, 
*** 2127,2132 ****
  	case VECTOR_CST:
  	case STRING_CST:
- 	case VECTOR_TYPE:
- 	case VOID_TYPE:
  	case BLOCK:
  	case PLACEHOLDER_EXPR:
--- 2218,2221 ----
*************** walk_tree (tree *tp, walk_tree_fn func, 
*** 2184,2188 ****
  		WALK_SUBTREE (DECL_SIZE (decl));
  		WALK_SUBTREE (DECL_SIZE_UNIT (decl));
- 		WALK_SUBTREE (TREE_TYPE (decl));
  	      }
  	    WALK_SUBTREE_TAIL (BIND_EXPR_BODY (*tp));
--- 2273,2276 ----
*************** walk_tree (tree *tp, walk_tree_fn func, 
*** 2197,2264 ****
  	  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
--- 2285,2288 ----
*************** declare_inline_vars (tree bind_expr, tre
*** 2499,2503 ****
  
        for (t = vars; t; t = TREE_CHAIN (t))
! 	vars->decl.seen_in_bind_expr = 1;
      }
  
--- 2523,2527 ----
  
        for (t = vars; t; t = TREE_CHAIN (t))
! 	DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
      }
  
*** tree-nested.c	28 Jun 2004 12:01:30 -0000	2.7
--- tree-nested.c	5 Jul 2004 13:34:19 -0000
*************** create_tmp_var_for (struct nesting_info 
*** 146,149 ****
--- 146,150 ----
    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;
  
*** tree.h	5 Jul 2004 09:35:27 -0000	1.540
--- tree.h	5 Jul 2004 13:34:28 -0000
*************** extern GTY (()) unsigned binfo_lang_slot
*** 1986,1989 ****
--- 1986,1994 ----
    (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.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]