aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2004-06-18 22:39:14 -0700
committerRichard Henderson <rth@gcc.gnu.org>2004-06-18 22:39:14 -0700
commitff98621c682005e2a224f62c1aa5028353a5357e (patch)
tree5791e7f8af3ac3bb999dd5a105aafb41d29af09e /gcc
parent048d99365055be4021508378e90a90987df38283 (diff)
downloadgcc-ff98621c682005e2a224f62c1aa5028353a5357e.zip
gcc-ff98621c682005e2a224f62c1aa5028353a5357e.tar.gz
gcc-ff98621c682005e2a224f62c1aa5028353a5357e.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/gimple-low.c43
-rw-r--r--gcc/gimplify.c7
-rw-r--r--gcc/tree-cfg.c28
4 files changed, 41 insertions, 45 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fb03211..6402c1e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c
index aac3341..98346cc 100644
--- a/gcc/gimple-low.c
+++ b/gcc/gimple-low.c
@@ -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);
-
- /* 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 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))
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 45d5e6e..2e7d30e 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -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;
}
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 25d5b06..1fad3da 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -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 ();