This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
fix c++/16036
- From: Richard Henderson <rth at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 18 Jun 2004 22:41:11 -0700
- Subject: 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 ----