re PR c++/16036 (Spurious "may be used uninitialized in this function" warning)

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

From-SVN: r83382
This commit is contained in:
Richard Henderson 2004-06-18 22:39:14 -07:00 committed by Richard Henderson
parent 048d993650
commit ff98621c68
4 changed files with 40 additions and 44 deletions

View File

@ -1,3 +1,11 @@
2004-06-18 Richard Henderson <rth@redhat.com>
PR c++/16036
* 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.
2004-06-18 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
* tree-ssa.c (raise_value): Removed.

View File

@ -67,6 +67,7 @@ lower_function_body (void)
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 ();
@ -83,25 +84,33 @@ lower_function_body (void)
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)
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))
{
tree t, x;
i = tsi_last (*body_p);
x = build (RETURN_EXPR, void_type_node, NULL);
annotate_with_locus (x, cfun->function_end_locus);
tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
}
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);
/* 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);
}
/* 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))

View File

@ -946,6 +946,13 @@ gimplify_return_expr (tree stmt, tree *pre_p)
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;
}

View File

@ -418,7 +418,6 @@ static void
make_edges (void)
{
basic_block bb;
edge e;
/* Create an edge from entry to the first block with executable
statements in it. */
@ -447,33 +446,6 @@ make_edges (void)
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 ();