diff mbox

PR c/68637: Rebuid array with the updated function pointer type

Message ID 20151201193514.GA4445@intel.com
State New
Headers show

Commit Message

H.J. Lu Dec. 1, 2015, 7:35 p.m. UTC
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.
---
 gcc/attribs.c                           | 18 +++++++++++++++++-
 gcc/testsuite/gcc.target/i386/pr68637.c | 10 ++++++++++
 2 files changed, 27 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr68637.c
diff mbox

Patch

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.c b/gcc/testsuite/gcc.target/i386/pr68637.c
new file mode 100644
index 0000000..c6fc6ba
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr68637.c
@@ -0,0 +1,10 @@ 
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -Werror " } */
+
+extern void (*bar[10]) (int, int) __attribute__ ((regparm (2)));
+
+void
+xxx (int i)
+{
+  bar[i] (1, 2);
+}