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++, tree-ssa] PATCH to fix c++/12453 (g++.dg/ext/stmtexpr1.C)


In RTL-land, we dealt with TARGET_EXPRs and their kin by passing down an
address so that they would all initialize the same address.  In tree-ssa we
are more direct about plugging in the actual variable we want to
initialize.  In the case of a TARGET_EXPR initialized by a STMT_EXPR, this
is a bit more complex, as the AGGR_INIT_EXPR which does the actual
initialization is buried way down inside the STMT_EXPR.

This patch adds support for finding the AGGR_INIT_EXPR in question so that
we can plug our variable into it, so we don't have to deal with the value
of the STMT_EXPR.

Tested athlon-pc-linux-gnu, applied to tree-ssa.

2003-12-18  Jason Merrill  <jason@redhat.com>

	PR c++/12453
	* c-simplify.c (stmt_expr_last_stmt): Split out from...
	(gimplify_stmt_expr): Here.
	* c-common.h: Declare it.
	* cp/cp-simplify.c (cp_gimplify_init_expr): Look inside STMT_EXPRs
	and COMPOUND_EXPRs to find an AGGR_INIT_EXPR.

*** c-common.h.~1~	2003-12-18 18:12:15.000000000 -0500
--- c-common.h	2003-12-17 14:08:50.000000000 -0500
*************** extern void c_warn_unused_result (tree *
*** 1291,1296 ****
--- 1291,1297 ----
  /* In c-simplify.c  */
  extern void c_genericize (tree);
  extern int c_gimplify_stmt (tree *);
+ extern tree stmt_expr_last_stmt (tree);
  
  extern void pch_init (void);
  extern int c_common_valid_pch (cpp_reader *pfile, const char *name, int fd);
*** c-simplify.c.~1~	2003-12-18 18:12:15.000000000 -0500
--- c-simplify.c	2003-12-18 16:15:41.000000000 -0500
*************** c_gimplify_expr (tree *expr_p, tree *pre
*** 935,940 ****
--- 935,984 ----
      }
  }
  
+ /* Returns the final EXPR_STMT which represents the return value of a
+    STMT_EXPR, or NULL_TREE if none.  */
+ 
+ tree
+ stmt_expr_last_stmt (tree stmt_expr)
+ {
+   tree body = STMT_EXPR_STMT (stmt_expr);
+   tree last_stmt, substmt;
+ 
+   /* Splice the last expression out of the STMT chain.  */
+   last_stmt = NULL_TREE;
+   for (substmt = COMPOUND_BODY (body); substmt;
+        substmt = TREE_CHAIN (substmt))
+     if (TREE_CODE (substmt) != SCOPE_STMT)
+       last_stmt = substmt;
+ 
+   if (last_stmt == NULL_TREE
+       || TREE_CODE (last_stmt) != EXPR_STMT
+       || (TREE_TYPE (last_stmt)
+ 	  && VOID_TYPE_P (TREE_TYPE (last_stmt))))
+     {
+       location_t loc;
+       if (last_stmt)
+ 	{
+ 	  loc.file = input_filename;
+ 	  loc.line = STMT_LINENO (last_stmt);
+ 	}
+       else if (EXPR_LOCUS (stmt_expr))
+ 	loc = *EXPR_LOCUS (stmt_expr);
+       else
+ 	loc = input_location;
+       warning ("%Hstatement-expressions should end with a "
+ 	       "non-void expression", &loc);
+       last_stmt = NULL_TREE;
+     }
+ 
+ #if defined ENABLE_CHECKING
+   if (last_stmt && !is_last_stmt_of_scope (last_stmt))
+     abort ();
+ #endif
+ 
+   return last_stmt;
+ }
+ 
  /* Gimplify a STMT_EXPR.  EXPR_P points to the expression to gimplify.
     After gimplification, if the STMT_EXPR returns a value, EXPR_P will
     point to a new temporary that holds that value; otherwise it will be
*************** gimplify_stmt_expr (tree *expr_p)
*** 955,989 ****
      }
    else
      {
!       tree last_stmt, last_expr, substmt;
  
!       /* Splice the last expression out of the STMT chain.  */
!       last_stmt = NULL_TREE;
!       for (substmt = COMPOUND_BODY (body); substmt;
! 	   substmt = TREE_CHAIN (substmt))
! 	if (TREE_CODE (substmt) != SCOPE_STMT)
! 	  last_stmt = substmt;
! 
!       if (last_stmt == NULL_TREE
! 	  || TREE_CODE (last_stmt) != EXPR_STMT
! 	  || (TREE_TYPE (last_stmt)
! 	      && VOID_TYPE_P (TREE_TYPE (last_stmt))))
! 	{
! 	  location_t loc;
! 	  if (last_stmt)
! 	    {
! 	      loc.file = input_filename;
! 	      loc.line = STMT_LINENO (last_stmt);
! 	    }
! 	  else if (EXPR_LOCUS (*expr_p))
! 	    loc = *EXPR_LOCUS (*expr_p);
! 	  else
! 	    loc = input_location;
! 	  warning ("%Hstatement-expressions should end with a "
! 		   "non-void expression", &loc);
! 	  last_expr = NULL_TREE;
! 	}
!       else
  	{
  	  last_expr = EXPR_STMT_EXPR (last_stmt);
  
--- 999,1008 ----
      }
    else
      {
!       tree last_stmt = stmt_expr_last_stmt (*expr_p);
!       tree last_expr = NULL_TREE;
  
!       if (last_stmt)
  	{
  	  last_expr = EXPR_STMT_EXPR (last_stmt);
  
*************** gimplify_stmt_expr (tree *expr_p)
*** 993,1003 ****
  	  EXPR_STMT_EXPR (last_stmt) = NULL_TREE;
  	}
  
- #if defined ENABLE_CHECKING
-       if (last_stmt && !is_last_stmt_of_scope (last_stmt))
- 	abort ();
- #endif
- 
        /* Genericize the block.  */
        c_gimplify_stmt (&body);
  
--- 1012,1017 ----
*** cp/cp-simplify.c.~1~	2003-12-18 18:12:15.000000000 -0500
--- cp/cp-simplify.c	2003-12-17 14:17:32.000000000 -0500
*************** cp_gimplify_init_expr (tree *expr_p, tre
*** 171,176 ****
--- 171,177 ----
  {
    tree from = TREE_OPERAND (*expr_p, 1);
    tree to = TREE_OPERAND (*expr_p, 0);
+   tree sub;
  
    /* If we are initializing something from a TARGET_EXPR, strip the
       TARGET_EXPR and initialize it directly.  */
*************** cp_gimplify_init_expr (tree *expr_p, tre
*** 181,196 ****
    if (TREE_CODE (from) == TARGET_EXPR)
      from = TARGET_EXPR_INITIAL (from);
  
    /* If we are initializing from an AGGR_INIT_EXPR, drop the INIT_EXPR and
       replace the slot operand with our target.
  
       Should we add a target parm to gimplify_expr instead?  No, as in this
       case we want to replace the INIT_EXPR.  */
!   if (TREE_CODE (from) == AGGR_INIT_EXPR)
      {
        gimplify_expr (&to, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
!       TREE_OPERAND (from, 2) = to;
        *expr_p = from;
      }
  }
  
--- 182,214 ----
    if (TREE_CODE (from) == TARGET_EXPR)
      from = TARGET_EXPR_INITIAL (from);
  
+   sub = from;
+ 
+   /* If we are initializing from a STMT_EXPR, extract the returned
+      expression.  */
+   if (TREE_CODE (from) == STMT_EXPR)
+     sub = EXPR_STMT_EXPR (stmt_expr_last_stmt (from));
+ 
+   /* Look through any COMPOUND_EXPRs.  */
+   while (TREE_CODE (sub) == COMPOUND_EXPR)
+     sub = TREE_OPERAND (sub, 1);
+ 
    /* If we are initializing from an AGGR_INIT_EXPR, drop the INIT_EXPR and
       replace the slot operand with our target.
  
       Should we add a target parm to gimplify_expr instead?  No, as in this
       case we want to replace the INIT_EXPR.  */
!   if (TREE_CODE (sub) == AGGR_INIT_EXPR)
      {
        gimplify_expr (&to, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
!       TREE_OPERAND (sub, 2) = to;
        *expr_p = from;
+ 
+       /* The initialization is now a side-effect, so the container can
+          become void.  This is important for a STMT_EXPR, so we don't try
+          to voidify it later by creating a temporary.  */
+       if (from != sub)
+ 	TREE_TYPE (from) = void_type_node;
      }
  }
  

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