re PR c++/16036 (Spurious "may be used uninitialized in this function" warning)
authorRichard Henderson <rth@redhat.com>
Sat, 19 Jun 2004 05:39:14 +0000 (22:39 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Sat, 19 Jun 2004 05:39:14 +0000 (22:39 -0700)
        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

gcc/ChangeLog
gcc/gimple-low.c
gcc/gimplify.c
gcc/tree-cfg.c

index fb0321165a915ba9d203b352d5626158976ce5ee..6402c1eb565dba1e393152ad3791404da8e75580 100644 (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.
index aac3341b8ccee7d4220be47d3d7b1dbb46e46150..98346cc2bf23b7358ccbad733e5f04073e5260e4 100644 (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);
-
-         /* 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))
index 45d5e6ec1a9c962df896482881bef5d3d99981dd..2e7d30e9dcecb5fdb5fc15a90c518e3ba40a7a67 100644 (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;
     }
 
index 25d5b06ef47712ecca3548d1782b629a548692e3..1fad3dabde68831eb688349b707f35b71a8214c1 100644 (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 ();