The resolver for ifunc functions might resolve to a non-local function. Tested on x86 and x86-64. OK for trunk?
H.J. --- gcc/ PR middle-end/71524 * symtab.c (symtab_node::binds_to_current_def_p): Return false for IFUNC resolver. gcc/testsuite/ PR middle-end/71524 * gcc.dg/pr71524.c: New test. --- gcc/symtab.c | 5 +++++ gcc/testsuite/gcc.dg/pr71524.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr71524.c diff --git a/gcc/symtab.c b/gcc/symtab.c index ded6ecc..1e4bd8c 100644 --- a/gcc/symtab.c +++ b/gcc/symtab.c @@ -2216,6 +2216,11 @@ symtab_node::binds_to_current_def_p (symtab_node *ref) { if (!definition) return false; + /* The resolver for ifunc functions might resolve to a non-local + function. */ + if (TREE_CODE (decl) == FUNCTION_DECL + && lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))) + return false; if (decl_binds_to_current_def_p (decl)) return true; diff --git a/gcc/testsuite/gcc.dg/pr71524.c b/gcc/testsuite/gcc.dg/pr71524.c new file mode 100644 index 0000000..1f975bd --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr71524.c @@ -0,0 +1,35 @@ +/* { dg-do run } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O2" } */ + +#include <stdio.h> + +extern void abort (void); + +static void *implementation (void) +{ + printf ("'ere I am JH\n"); + return 0; +} + +static void *resolver (void) +{ + return (void *)implementation; +} + +static int magic (void) __attribute__ ((ifunc ("resolver"))); + +void * +get_magic (void) +{ + return &magic; +} + +int +main () +{ + if (get_magic () != &magic) + abort (); + + return magic () != 0; +} -- 2.7.4