diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2016-06-13 13:38:22 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2016-06-23 14:09:24 -0700 |
commit | 0b0b5470fcc0e20b368ae9556d449258bae9609c (patch) | |
tree | 088fa211e3e36ec990167ed0efed9689341672be | |
parent | c1c86a8082f40a0c87bfb8d893590546fefd013b (diff) | |
download | gcc-0b0b5470fcc0e20b368ae9556d449258bae9609c.tar.gz |
IFUNC resolver may resolve to a non-local function
The resolver for ifunc functions might resolve to a non-local function.
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.
-rw-r--r-- | gcc/symtab.c | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr71524.c | 35 |
2 files changed, 40 insertions, 0 deletions
diff --git a/gcc/symtab.c b/gcc/symtab.c index ded6ecc17d5..1e4bd8cad87 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 00000000000..1f975bd3173 --- /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; +} |