diff options
author | Ian Lance Taylor <ian@c2micro.com> | 2005-01-27 14:36:17 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@c2micro.com> | 2005-01-27 14:36:17 +0000 |
commit | 8c9f6e8bc2513b6d6f005da06ab358efe703d99e (patch) | |
tree | c04e5a0433039c3cd49001e6fc91f301c7470db5 | |
parent | 12950577fa5e954180aa604ad93063793a1c3701 (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/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/gimple-low.c | 50 | ||||
-rw-r--r-- | gcc/tree-inline.c | 4 |
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", |