Commit 6737ba67 by Ian Lance Taylor Committed by Ian Lance Taylor

re PR middle-end/19583 (Incorrect diagnostic: control may reach end of non-void…

re PR middle-end/19583 (Incorrect diagnostic: control may reach end of non-void function '...' being inlined)

	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
parent 9d72d996
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> 2005-01-27 Jakub Jelinek <jakub@redhat.com>
* config/i386/i386.h (CALL_USED_REGISTERS): Fix comment pastos. * config/i386/i386.h (CALL_USED_REGISTERS): Fix comment pastos.
......
...@@ -263,6 +263,53 @@ lower_bind_expr (tree_stmt_iterator *tsi, struct lower_data *data) ...@@ -263,6 +263,53 @@ lower_bind_expr (tree_stmt_iterator *tsi, struct lower_data *data)
tsi_delink (tsi); 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 /* 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 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. don't know. This is used only to avoid stupidly generating extra code.
...@@ -297,6 +344,9 @@ block_may_fallthru (tree block) ...@@ -297,6 +344,9 @@ block_may_fallthru (tree block)
case BIND_EXPR: case BIND_EXPR:
return block_may_fallthru (BIND_EXPR_BODY (stmt)); return block_may_fallthru (BIND_EXPR_BODY (stmt));
case TRY_CATCH_EXPR:
return try_catch_may_fallthru (stmt);
case TRY_FINALLY_EXPR: case TRY_FINALLY_EXPR:
return block_may_fallthru (TREE_OPERAND (stmt, 1)); return block_may_fallthru (TREE_OPERAND (stmt, 1));
......
...@@ -1616,9 +1616,13 @@ expand_call_inline (tree *tp, int *walk_subtrees, void *data) ...@@ -1616,9 +1616,13 @@ expand_call_inline (tree *tp, int *walk_subtrees, void *data)
id->current_node = edge->callee; id->current_node = edge->callee;
copy = copy_body (id); 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 if (warn_return_type
&& !TREE_NO_WARNING (fn) && !TREE_NO_WARNING (fn)
&& !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fn))) && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fn)))
&& return_slot_addr == NULL_TREE
&& block_may_fallthru (copy)) && block_may_fallthru (copy))
{ {
warning ("control may reach end of non-void function %qD being inlined", warning ("control may reach end of non-void function %qD being inlined",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment