summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2016-06-13 13:38:22 -0700
committerH.J. Lu <hjl.tools@gmail.com>2016-06-23 14:09:24 -0700
commit0b0b5470fcc0e20b368ae9556d449258bae9609c (patch)
tree088fa211e3e36ec990167ed0efed9689341672be
parentc1c86a8082f40a0c87bfb8d893590546fefd013b (diff)
downloadgcc-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.c5
-rw-r--r--gcc/testsuite/gcc.dg/pr71524.c35
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;
+}