[PATCH] Fix ICE in gimplify_call_expr (PR middle-end/26092)
Jakub Jelinek
jakub@redhat.com
Wed Feb 8 15:26:00 GMT 2006
Hi!
On the attached testcase GCC segfaults, because while get_callee_fndecl
(*expr_p) before gimplification is a builtin (malloc in this case; *expr_p
is a call through a const fn pointer with DECL_INITIAL set to the builtin),
after gimplification the fn pointer is copied into a temporary variable
and so no longer has DECL_INITIAL malloc and thus passes NULL to
fold_builtin.
Fixed by verifying again whether the expr is a builtin or not.
While looking at it, I have noticed that on the other side there is a
completely useless get_callee_fndecl (*expr_p) call, so I have removed
that too.
Bootstrapped/regtested on i386-linux, ok for trunk/4.1?
2006-02-08 Jakub Jelinek <jakub@redhat.com>
PR middle-end/26092
* gimplify.c (gimplify_call_expr): Don't call get_callee_fndecl
twice if decl is a builtin. When trying again, call get_callee_fndecl
first to verify it is still a builtin.
* gcc.c-torture/compile/20060208-1.c: New test.
--- gcc/gimplify.c.jj 2006-02-08 08:09:13.000000000 +0100
+++ gcc/gimplify.c 2006-02-08 12:53:00.000000000 +0100
@@ -1970,9 +1970,8 @@ gimplify_call_expr (tree *expr_p, tree *
decl = get_callee_fndecl (*expr_p);
if (decl && DECL_BUILT_IN (decl))
{
- tree fndecl = get_callee_fndecl (*expr_p);
tree arglist = TREE_OPERAND (*expr_p, 1);
- tree new = fold_builtin (fndecl, arglist, !want_value);
+ tree new = fold_builtin (decl, arglist, !want_value);
if (new && new != *expr_p)
{
@@ -2026,19 +2025,22 @@ gimplify_call_expr (tree *expr_p, tree *
TREE_OPERAND (*expr_p, 1) = nreverse (TREE_OPERAND (*expr_p, 1));
/* Try this again in case gimplification exposed something. */
- if (ret != GS_ERROR && decl && DECL_BUILT_IN (decl))
+ if (ret != GS_ERROR)
{
- tree fndecl = get_callee_fndecl (*expr_p);
- tree arglist = TREE_OPERAND (*expr_p, 1);
- tree new = fold_builtin (fndecl, arglist, !want_value);
-
- if (new && new != *expr_p)
+ decl = get_callee_fndecl (*expr_p);
+ if (decl && DECL_BUILT_IN (decl))
{
- /* There was a transformation of this call which computes the
- same value, but in a more efficient way. Return and try
- again. */
- *expr_p = new;
- return GS_OK;
+ tree arglist = TREE_OPERAND (*expr_p, 1);
+ tree new = fold_builtin (decl, arglist, !want_value);
+
+ if (new && new != *expr_p)
+ {
+ /* There was a transformation of this call which computes the
+ same value, but in a more efficient way. Return and try
+ again. */
+ *expr_p = new;
+ return GS_OK;
+ }
}
}
--- gcc/testsuite/gcc.c-torture/execute/20060208-1.c.jj 2006-02-08 13:00:08.000000000 +0100
+++ gcc/testsuite/gcc.c-torture/execute/20060208-1.c 2006-02-08 12:58:58.000000000 +0100
@@ -0,0 +1,10 @@
+/* PR middle-end/26092 */
+typedef __SIZE_TYPE__ size_t;
+extern void *malloc (size_t);
+
+void *(*const foo) (size_t) = malloc;
+
+void *test (void)
+{
+ return (*foo) (3);
+}
Jakub
More information about the Gcc-patches
mailing list