re PR middle-end/19583 (Incorrect diagnostic: control may reach end of non-void funct...
authorIan Lance Taylor <ian@c2micro.com>
Thu, 27 Jan 2005 14:36:17 +0000 (14:36 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Thu, 27 Jan 2005 14:36:17 +0000 (14:36 +0000)
PR middle-end/19583
* gimple-low.c (try_catch_may_fallthru): New static function.
(block_may_fallthru): Handle TRY_CATCH_EXPR.
* tree-inline.c (expand_call_inline): Don't warn about reaching
the end of a non-void function being inlined if the function uses
a return slot.

From-SVN: r94323

gcc/ChangeLog
gcc/gimple-low.c
gcc/tree-inline.c

index 47c64d85887fa36074b4112e11611ddd578494e6..02cf5fef9aa38c78ebffcb3075e73afe109452ed 100644 (file)
@@ -1,3 +1,12 @@
+2005-01-27  Ian Lance Taylor  <ian@c2micro.com>
+
+       PR middle-end/19583
+       * gimple-low.c (try_catch_may_fallthru): New static function.
+       (block_may_fallthru): Handle TRY_CATCH_EXPR.
+       * tree-inline.c (expand_call_inline): Don't warn about reaching
+       the end of a non-void function being inlined if the function uses
+       a return slot.
+
 2005-01-27  Jakub Jelinek  <jakub@redhat.com>
 
        * config/i386/i386.h (CALL_USED_REGISTERS): Fix comment pastos.
index fe63addd4a7a6843ecb99bdb7a68a1120360b5a9..5165a9a788bc5be528c76b3049f1aa7effade274 100644 (file)
@@ -263,6 +263,53 @@ lower_bind_expr (tree_stmt_iterator *tsi, struct lower_data *data)
   tsi_delink (tsi);
 }
 
+/* Try to determine whether a TRY_CATCH expression can fall through.
+   This is a subroutine of block_may_fallthru.  */
+
+static bool
+try_catch_may_fallthru (tree stmt)
+{
+  tree_stmt_iterator i;
+
+  /* If the TRY block can fall through, the whole TRY_CATCH can
+     fall through.  */
+  if (block_may_fallthru (TREE_OPERAND (stmt, 0)))
+    return true;
+
+  i = tsi_start (TREE_OPERAND (stmt, 1));
+  switch (TREE_CODE (tsi_stmt (i)))
+    {
+    case CATCH_EXPR:
+      /* We expect to see a sequence of CATCH_EXPR trees, each with a
+        catch expression and a body.  The whole TRY_CATCH may fall
+        through iff any of the catch bodies falls through.  */
+      for (; !tsi_end_p (i); tsi_next (&i))
+       {
+         if (block_may_fallthru (CATCH_BODY (tsi_stmt (i))))
+           return true;
+       }
+      return false;
+
+    case EH_FILTER_EXPR:
+      /* If the exception does not match EH_FILTER_TYPES, we will
+        execute EH_FILTER_FAILURE, and we will fall through if that
+        falls through.  If the exception does match EH_FILTER_TYPES,
+        we will fall through.  We don't know which exceptions may be
+        generated, so we just check for EH_FILTER_TYPES being NULL,
+        in which case we know that that the exception does not
+        match.  */
+      return (EH_FILTER_TYPES (tsi_stmt (i)) != NULL
+             || block_may_fallthru (EH_FILTER_FAILURE (tsi_stmt (i))));
+
+    default:
+      /* This case represents statements to be executed when an
+        exception occurs.  Those statements are implicitly followed
+        by a RESX_EXPR to resume execution after the exception.  So
+        in this case the TRY_CATCH never falls through.  */
+      return false;
+    }
+}
+
 /* Try to determine if we can fall out of the bottom of BLOCK.  This guess
    need not be 100% accurate; simply be conservative and return true if we
    don't know.  This is used only to avoid stupidly generating extra code.
@@ -297,6 +344,9 @@ block_may_fallthru (tree block)
     case BIND_EXPR:
       return block_may_fallthru (BIND_EXPR_BODY (stmt));
 
+    case TRY_CATCH_EXPR:
+      return try_catch_may_fallthru (stmt);
+
     case TRY_FINALLY_EXPR:
       return block_may_fallthru (TREE_OPERAND (stmt, 1));
 
index 4827fa203588c44b52a9ce5742ce77e439686336..120bab0fb21e4932f93b58b40b8593236a8add9e 100644 (file)
@@ -1616,9 +1616,13 @@ expand_call_inline (tree *tp, int *walk_subtrees, void *data)
     id->current_node = edge->callee;
     copy = copy_body (id);
 
+    /* If the function uses a return slot, then it may legitimately
+       fall through while still returning a value, so we have to skip
+       the warning here.  */
     if (warn_return_type
        && !TREE_NO_WARNING (fn)
        && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fn)))
+       && return_slot_addr == NULL_TREE
        && block_may_fallthru (copy))
       {
        warning ("control may reach end of non-void function %qD being inlined",