[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