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:
parent
048d993650
commit
ff98621c68
@ -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.
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 ();
|
||||
|
Loading…
Reference in New Issue
Block a user