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 c++/16036


I think there are issues with varibles live across abnormal edges
that probably ought to be addressed.  However, nothing comes to
mind immediately, and simply disabling the warning for this
variable ought to be safe enough.


r~


        * gimple-low.c (lower_function_body): Generate return statement for
        fall off the end of the function here ...
        * tree-cfg.c (make_edges): ... instead of here.
        * gimplify.c (gimplify_return_expr): Mark return temp TREE_NO_WARNING.

Index: gimple-low.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gimple-low.c,v
retrieving revision 2.4
diff -c -p -d -r2.4 gimple-low.c
*** gimple-low.c	8 Jun 2004 16:29:55 -0000	2.4
--- gimple-low.c	19 Jun 2004 05:35:04 -0000
*************** lower_function_body (void)
*** 67,72 ****
--- 67,73 ----
    tree *body_p = &DECL_SAVED_TREE (current_function_decl);
    tree bind = *body_p;
    tree_stmt_iterator i;
+   tree t, x;
  
    if (TREE_CODE (bind) != BIND_EXPR)
      abort ();
*************** lower_function_body (void)
*** 83,107 ****
    tsi_link_after (&i, bind, TSI_NEW_STMT);
    lower_bind_expr (&i, &data);
  
!   /* If we lowered any return statements, emit the representative at the
!      end of the function.  */
!   if (data.return_statements)
      {
!       tree t, x;
!       i = tsi_last (*body_p);
  
!       for (t = data.return_statements; t ; t = TREE_CHAIN (t))
! 	{
! 	  x = build (LABEL_EXPR, void_type_node, TREE_PURPOSE (t));
!           tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
  
! 	  /* Remove the line number from the representative return statement.
! 	     It now fills in for many such returns.  Failure to remove this
! 	     will result in incorrect results for coverage analysis.  */
! 	  x = TREE_VALUE (t);
! 	  SET_EXPR_LOCUS (x, NULL);
!           tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
!         }
      }
  
    if (data.block != DECL_INITIAL (current_function_decl))
--- 84,116 ----
    tsi_link_after (&i, bind, TSI_NEW_STMT);
    lower_bind_expr (&i, &data);
  
!   i = tsi_last (*body_p);
! 
!   /* If the function falls off the end, we need a null return statement.
!      If we've already got one in the return_statements list, we don't
!      need to do anything special.  Otherwise build one by hand.  */
!   if (block_may_fallthru (*body_p)
!       && (data.return_statements == NULL
!           || TREE_OPERAND (TREE_VALUE (data.return_statements), 0) != NULL))
      {
!       x = build (RETURN_EXPR, void_type_node, NULL);
!       annotate_with_locus (x, cfun->function_end_locus);
!       tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
!     }
  
!   /* If we lowered any return statements, emit the representative
!      at the end of the function.  */
!   for (t = data.return_statements ; t ; t = TREE_CHAIN (t))
!     {
!       x = build (LABEL_EXPR, void_type_node, TREE_PURPOSE (t));
!       tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
  
!       /* Remove the line number from the representative return statement.
! 	 It now fills in for many such returns.  Failure to remove this
! 	 will result in incorrect results for coverage analysis.  */
!       x = TREE_VALUE (t);
!       SET_EXPR_LOCUS (x, NULL);
!       tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
      }
  
    if (data.block != DECL_INITIAL (current_function_decl))
Index: gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gimplify.c,v
retrieving revision 2.17
diff -c -p -d -r2.17 gimplify.c
*** gimplify.c	17 Jun 2004 22:35:50 -0000	2.17
--- gimplify.c	19 Jun 2004 05:35:04 -0000
*************** gimplify_return_expr (tree stmt, tree *p
*** 946,951 ****
--- 946,958 ----
    else
      {
        result = create_tmp_var (TREE_TYPE (result_decl), NULL);
+ 
+       /* ??? With complex control flow (usually involving abnormal edges),
+ 	 we can wind up warning about an uninitialized value for this.  Due
+ 	 to how this variable is constructed and initialized, this is never
+ 	 true.  Give up and never warn.  */
+       TREE_NO_WARNING (result) = 1;
+ 
        gimplify_ctxp->return_temp = result;
      }
  
Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-cfg.c,v
retrieving revision 2.14
diff -c -p -d -r2.14 tree-cfg.c
*** tree-cfg.c	17 Jun 2004 18:13:11 -0000	2.14
--- tree-cfg.c	19 Jun 2004 05:35:04 -0000
*************** static void
*** 418,424 ****
  make_edges (void)
  {
    basic_block bb;
-   edge e;
  
    /* Create an edge from entry to the first block with executable
       statements in it.  */
--- 418,423 ----
*************** make_edges (void)
*** 447,479 ****
  	make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
      }
  
-   /* If there is a fallthru edge to exit out of the last block, transform it
-      to a return statement.  */
-   for (e = EXIT_BLOCK_PTR->prev_bb->succ; e; e = e->succ_next)
-     if (e->flags & EDGE_FALLTHRU)
-       break;
- 
-   if (e && e->dest == EXIT_BLOCK_PTR)
-     {
-       block_stmt_iterator bsi;
-       basic_block ret_bb = EXIT_BLOCK_PTR->prev_bb;
-       tree x;
- 
-       /* If E->SRC ends with a call that has an abnormal edge (for EH or
- 	 nonlocal goto), then we will need to split the edge to insert
- 	 an explicit return statement.  */
-       if (e != ret_bb->succ || e->succ_next)
- 	{
- 	  ret_bb = split_edge (e);
- 	  e = ret_bb->succ;
- 	}
-       e->flags &= ~EDGE_FALLTHRU;
- 
-       x = build (RETURN_EXPR, void_type_node, NULL_TREE);
-       bsi = bsi_last (ret_bb);
-       bsi_insert_after (&bsi, x, BSI_NEW_STMT);
-     }
- 
    /* We do not care about fake edges, so remove any that the CFG
       builder inserted for completeness.  */
    remove_fake_edges ();
--- 446,451 ----


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