aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@c2micro.com>2005-01-27 14:36:17 +0000
committerIan Lance Taylor <ian@c2micro.com>2005-01-27 14:36:17 +0000
commit8c9f6e8bc2513b6d6f005da06ab358efe703d99e (patch)
treec04e5a0433039c3cd49001e6fc91f301c7470db5
parent12950577fa5e954180aa604ad93063793a1c3701 (diff)
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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@94323 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/gimple-low.c50
-rw-r--r--gcc/tree-inline.c4
3 files changed, 63 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 47c64d85887..02cf5fef9aa 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c
index fe63addd4a7..5165a9a788b 100644
--- a/gcc/gimple-low.c
+++ b/gcc/gimple-low.c
@@ -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));
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 4827fa20358..120bab0fb21 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -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",