This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] PR c/68637: Rebuild array with the updated function pointer type


On Tue, Dec 1, 2015 at 11:35 AM, H.J. Lu <hongjiu.lu@intel.com> wrote:
> When we apply function attribute to array of function pointer, we
> need to rebuild array with the updated function pointer type.
>
> gcc/
>
>         PR c/68637
>         * attribs.c (decl_attributes): Rebuid array with the updated
>         * function pointer type.
>
> gcc/testsuite/
>
>         PR c/68637
>         * gcc.target/i386/pr68637.c: New test.

Here is the patch with run-time test.

-- 
H.J.
From 4e86b66144fba46b9b2ae88cf8d31179024ba7b8 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Tue, 1 Dec 2015 11:29:39 -0800
Subject: [PATCH] Rebuild array with the updated function pointer type

When we apply function attribute to array of function pointer, we need
to rebuild array with the updated function pointer type.

gcc/

	PR c/68637
	* attribs.c (decl_attributes): Rebuild array with the updated
	function pointer type.

gcc/testsuite/

	PR c/68637
	* gcc.target/i386/pr68637-1.c: New test.
	* gcc.target/i386/pr68637-2.c: Likewise.
---
 gcc/attribs.c                             | 18 +++++++++++++++++-
 gcc/testsuite/gcc.target/i386/pr68637-1.c | 10 ++++++++++
 gcc/testsuite/gcc.target/i386/pr68637-2.c | 25 +++++++++++++++++++++++++
 3 files changed, 52 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr68637-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr68637-2.c

diff --git a/gcc/attribs.c b/gcc/attribs.c
index affb21d..0be5ebf 100644
--- a/gcc/attribs.c
+++ b/gcc/attribs.c
@@ -494,9 +494,18 @@ decl_attributes (tree *node, tree attributes, int flags)
 	  flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
 	}
 
+      tree array_type = (TREE_CODE (*anode) == ARRAY_TYPE
+			 ? *anode
+			 : NULL_TREE);
+
       if (spec->function_type_required && TREE_CODE (*anode) != FUNCTION_TYPE
 	  && TREE_CODE (*anode) != METHOD_TYPE)
 	{
+	  /* We need to rebuid array with the updated function pointer
+	     type later. */
+	  if (array_type)
+	    *anode = TREE_TYPE (*anode);
+
 	  if (TREE_CODE (*anode) == POINTER_TYPE
 	      && (TREE_CODE (TREE_TYPE (*anode)) == FUNCTION_TYPE
 		  || TREE_CODE (TREE_TYPE (*anode)) == METHOD_TYPE))
@@ -617,7 +626,14 @@ decl_attributes (tree *node, tree attributes, int flags)
 	  if (fn_ptr_quals)
 	    fn_ptr_tmp = build_qualified_type (fn_ptr_tmp, fn_ptr_quals);
 	  if (DECL_P (*node))
-	    TREE_TYPE (*node) = fn_ptr_tmp;
+	    {
+	      if (array_type)
+		TREE_TYPE (*node)
+		  = build_array_type (fn_ptr_tmp,
+				      TYPE_DOMAIN (array_type));
+	      else
+		TREE_TYPE (*node) = fn_ptr_tmp;
+	    }
 	  else
 	    {
 	      gcc_assert (TREE_CODE (*node) == POINTER_TYPE);
diff --git a/gcc/testsuite/gcc.target/i386/pr68637-1.c b/gcc/testsuite/gcc.target/i386/pr68637-1.c
new file mode 100644
index 0000000..b1661fd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr68637-1.c
@@ -0,0 +1,10 @@
+/* { dg-do run { target ia32 } } */
+/* { dg-additional-sources pr68637-2.c } */
+
+extern void (*bar[]) (int, int) __attribute__ ((regparm (2)));
+
+void
+foo (void)
+{
+  bar[0] (1, 2);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr68637-2.c b/gcc/testsuite/gcc.target/i386/pr68637-2.c
new file mode 100644
index 0000000..7d9654d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr68637-2.c
@@ -0,0 +1,25 @@
+/* { dg-do compile { target ia32 } } */
+
+static void 
+__attribute__ ((regparm (2)))
+bar0 (int i, int j)
+{
+  if (i != 1 || j != 2)
+    __builtin_abort ();
+}
+
+typedef void (*func_t) (int, int) __attribute__ ((regparm (2)));
+
+func_t bar[] =
+{
+  bar0,
+};
+
+extern void foo (void);
+
+int
+main ()
+{
+  foo ();
+  return 0;
+}
-- 
2.5.0


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]