On Tue, Dec 1, 2015 at 11:35 AM, H.J. Lu <hongjiu...@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.to...@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