diff options
author | Richard Henderson <rth@redhat.com> | 2004-06-18 22:39:14 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2004-06-18 22:39:14 -0700 |
commit | ff98621c682005e2a224f62c1aa5028353a5357e (patch) | |
tree | 5791e7f8af3ac3bb999dd5a105aafb41d29af09e /gcc | |
parent | 048d99365055be4021508378e90a90987df38283 (diff) | |
download | gcc-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/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/gimple-low.c | 43 | ||||
-rw-r--r-- | gcc/gimplify.c | 7 | ||||
-rw-r--r-- | gcc/tree-cfg.c | 28 |
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 (); |