summaryrefslogtreecommitdiff
path: root/gcc/tree-tailcall.c
diff options
context:
space:
mode:
authorZdenek Dvorak <dvorakz@suse.cz>2004-10-07 16:21:15 +0200
committerZdenek Dvorak <rakdver@gcc.gnu.org>2004-10-07 14:21:15 +0000
commit14de86fa0a7305603e08f42e6fa5ba4dbd2c2c7d (patch)
tree6bb027787886f6e267f7de6f793add2b2a8ba963 /gcc/tree-tailcall.c
parentca05904340457c4c7dbdb15bc589ab980434fa53 (diff)
downloadgcc-14de86fa0a7305603e08f42e6fa5ba4dbd2c2c7d.tar.gz
re PR tree-optimization/17749 (ICE with recursive function)
PR tree-optimization/17749 * tree-tailcall.c (find_tail_calls): Check that parameter is a gimple_reg. From-SVN: r88689
Diffstat (limited to 'gcc/tree-tailcall.c')
-rw-r--r--gcc/tree-tailcall.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c
index a6c44933f79..158a2d1d6fb 100644
--- a/gcc/tree-tailcall.c
+++ b/gcc/tree-tailcall.c
@@ -431,15 +431,27 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
param = TREE_CHAIN (param), args = TREE_CHAIN (args))
{
tree arg = TREE_VALUE (args);
- if (param != arg
- /* Make sure there are no problems with copying. Note we must
+ if (param != arg)
+ {
+ /* Make sure there are no problems with copying. The parameter
have a copyable type and the two arguments must have reasonably
equivalent types. The latter requirement could be relaxed if
we emitted a suitable type conversion statement. */
- && (!is_gimple_reg_type (TREE_TYPE (param))
+ if (!is_gimple_reg_type (TREE_TYPE (param))
|| !lang_hooks.types_compatible_p (TREE_TYPE (param),
- TREE_TYPE (arg))))
- break;
+ TREE_TYPE (arg)))
+ break;
+
+ /* The parameter should be a real operand, so that phi node
+ created for it at the start of the function has the meaning
+ of copying the value. This test implies is_gimple_reg_type
+ from the previous condition, however this one could be
+ relaxed by being more careful with copying the new value
+ of the parameter (emitting appropriate MODIFY_EXPR and
+ updating the virtual operands). */
+ if (!is_gimple_reg (param))
+ break;
+ }
}
if (!args && !param)
tail_recursion = true;