From 6f538523d1e363cb51f08b52e31062304352e543 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@redhat.com>
Date: Mon, 13 Feb 2006 22:28:03 +0100
Subject: [PATCH] re PR middle-end/26092 (ICE on const function pointer
 assigned to a builtin function)

	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.

From-SVN: r110927
---
 gcc/ChangeLog                                 |  7 +++++
 gcc/gimplify.c                                | 28 ++++++++++---------
 gcc/testsuite/ChangeLog                       |  5 ++++
 .../gcc.c-torture/compile/20060208-1.c        | 10 +++++++
 4 files changed, 37 insertions(+), 13 deletions(-)
 create mode 100644 gcc/testsuite/gcc.c-torture/compile/20060208-1.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 15c3fc47c195..46d5b68e37b9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2006-02-13  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.
+
 2006-02-13  Geoffrey Keating  <geoffk@apple.com>
 
 	* dwarf2out.c (base_type_die): Don't add AT_name here.
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 710569888ec3..82e747f00709 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -1970,9 +1970,8 @@ gimplify_call_expr (tree *expr_p, tree *pre_p, bool want_value)
   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 *pre_p, bool want_value)
     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;
+	    }
 	}
     }
 
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 113914077f7b..1f2fdb7e55f1 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2006-02-13  Jakub Jelinek  <jakub@redhat.com>
+
+	PR middle-end/26092
+	* gcc.c-torture/compile/20060208-1.c: New test.
+
 2006-02-13  Paul Thomas  <pault@gcc.gnu.org>
 
 	PR fortran/26074
diff --git a/gcc/testsuite/gcc.c-torture/compile/20060208-1.c b/gcc/testsuite/gcc.c-torture/compile/20060208-1.c
new file mode 100644
index 000000000000..01e471a7b0ca
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20060208-1.c
@@ -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);
+}
-- 
GitLab