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]

C++ PATCH to build_new_1


The latest merge from the trunk into tree-ssa caused breakage in several
testcases that use array new.  This turned out to be because the data_addr
TARGET_EXPR was appearing twice in the expression, which confused the
gimplifier.  This patch fixes that.

While I was there, I undid some of Mark's reorganization; I prefer my old
way of building up the return value, as it doesn't require us to check if
rval is null and allows us to strip all TARGET_EXPRs in the simple case.

Tested i686-pc-linux-gnu, applied to trunk and tree-ssa.

2003-05-08  Jason Merrill  <jason@redhat.com>

	* init.c (build_new_1): Don't reuse a TARGET_EXPR in an
	expression.  Undo some of the recent reorg.

*** init.c.~1~	2003-05-07 11:15:48.000000000 -0400
--- init.c	2003-05-08 01:28:40.000000000 -0400
*************** build_new_1 (exp)
*** 2172,2177 ****
--- 2172,2178 ----
       a VAR_DECL and is therefore reusable.  */
    tree alloc_node;
    tree alloc_fn;
+   tree cookie_expr, init_expr;
    int has_array = 0;
    enum tree_code code;
    int nothrow, check_new;
*************** build_new_1 (exp)
*** 2357,2369 ****
       can use it more than once.  */
    full_pointer_type = build_pointer_type (full_type);
    alloc_expr = get_target_expr (build_nop (full_pointer_type, alloc_call));
!   alloc_node = TREE_OPERAND (alloc_expr, 0);
!   rval = NULL_TREE;
  
    if (cookie_size)
      {
        tree cookie;
-       tree cookie_expr;
  
        /* Adjust so we're pointing to the start of the object.  */
        data_addr = get_target_expr (build (PLUS_EXPR, full_pointer_type,
--- 2358,2368 ----
       can use it more than once.  */
    full_pointer_type = build_pointer_type (full_type);
    alloc_expr = get_target_expr (build_nop (full_pointer_type, alloc_call));
!   alloc_node = TARGET_EXPR_SLOT (alloc_expr);
  
    if (cookie_size)
      {
        tree cookie;
  
        /* Adjust so we're pointing to the start of the object.  */
        data_addr = get_target_expr (build (PLUS_EXPR, full_pointer_type,
*************** build_new_1 (exp)
*** 2377,2394 ****
        cookie = build_indirect_ref (cookie, NULL);
  
        cookie_expr = build (MODIFY_EXPR, sizetype, cookie, nelts);
!       TREE_SIDE_EFFECTS (cookie_expr) = 1;
!       rval = build (COMPOUND_EXPR, void_type_node, data_addr, cookie_expr);
!       data_addr = TREE_OPERAND (data_addr, 0);
      }
    else
!     data_addr = alloc_node;
  
    /* Now initialize the allocated object.  */
    if (is_initialized)
      {
-       tree init_expr;
- 
        init_expr = build_indirect_ref (data_addr, NULL);
  
        if (init == void_zero_node)
--- 2376,2392 ----
        cookie = build_indirect_ref (cookie, NULL);
  
        cookie_expr = build (MODIFY_EXPR, sizetype, cookie, nelts);
!       data_addr = TARGET_EXPR_SLOT (data_addr);
      }
    else
!     {
!       cookie_expr = NULL_TREE;
!       data_addr = alloc_node;
!     }
  
    /* Now initialize the allocated object.  */
    if (is_initialized)
      {
        init_expr = build_indirect_ref (data_addr, NULL);
  
        if (init == void_zero_node)
*************** build_new_1 (exp)
*** 2502,2525 ****
  				end));
  	    }
  	}
- 
-       if (rval)
- 	rval = build (COMPOUND_EXPR, TREE_TYPE (init_expr), rval, init_expr);
-       else
- 	rval = init_expr;
      }
  
!   rval = build (COMPOUND_EXPR, TREE_TYPE (alloc_node), rval, data_addr);
  
!   if (check_new)
      {
!       tree ifexp = cp_build_binary_op (NE_EXPR, alloc_node, integer_zero_node);
!       rval = build_conditional_expr (ifexp, rval, alloc_node);
!     }
  
!   /* Perform the allocation before anything else, so that ALLOC_NODE
!      has been initialized before we start using it.  */
!   rval = build (COMPOUND_EXPR, TREE_TYPE (rval), alloc_expr, rval);
  
    /* Convert to the final type.  */
    return build_nop (pointer_type, rval);
--- 2500,2535 ----
  				end));
  	    }
  	}
      }
+   else
+     init_expr = NULL_TREE;
+ 
+   /* Now build up the return value in reverse order.  */
  
!   rval = data_addr;
  
!   if (init_expr)
!     rval = build (COMPOUND_EXPR, TREE_TYPE (rval), init_expr, rval);
!   if (cookie_expr)
!     rval = build (COMPOUND_EXPR, TREE_TYPE (rval), cookie_expr, rval);
! 
!   if (rval == alloc_node)
!     /* If we don't have an initializer or a cookie, strip the TARGET_EXPR
!        and return the call (which doesn't need to be adjusted).  */
!     rval = TARGET_EXPR_INITIAL (alloc_expr);
!   else
      {
!       if (check_new)
! 	{
! 	  tree ifexp = cp_build_binary_op (NE_EXPR, alloc_node,
! 					   integer_zero_node);
! 	  rval = build_conditional_expr (ifexp, rval, alloc_node);
! 	}
  
!       /* Perform the allocation before anything else, so that ALLOC_NODE
! 	 has been initialized before we start using it.  */
!       rval = build (COMPOUND_EXPR, TREE_TYPE (rval), alloc_expr, rval);
!     }
  
    /* Convert to the final type.  */
    return build_nop (pointer_type, rval);

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