Hi

According to gnu document of function attributes, neither weakref nor alias
could be attached to a function defined in current translation unit.
Although GCC checks the attributes under some circumstances, it still fails
on some cases and even causes ICE.

This patch checks whether alias/weakref attribute attaches on a function
declaration which has body, and removes the attribute later.
This also avoid the ICE.

Bootstrapped/regtested on x86_64-linux, ok for GCC10?

Regards
JunMa


gcc/ChangeLog

2019-03-26  Jun Ma <ju...@linux.alibaba.com>

    PR89341
    * cgraphunit.c (handle_alias_pairs): Check whether alias attribute attaches
    on a function declaration which has body.

gcc/testsuite/ChangeLog

2019-03-26  Jun Ma <ju...@linux.alibaba.com>

    PR89341
    * gcc.dg/attr-alias-6.c: New test.
    * gcc.dg/attr-weakref-5.c: Likewise.
---
 gcc/cgraphunit.c                      | 11 ++++++++---
 gcc/testsuite/gcc.dg/attr-alias-6.c   |  4 ++++
 gcc/testsuite/gcc.dg/attr-weakref-5.c |  4 ++++
 3 files changed, 16 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/attr-alias-6.c
 create mode 100644 gcc/testsuite/gcc.dg/attr-weakref-5.c

diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 8bfbd0b..733e184 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -1405,14 +1405,20 @@ handle_alias_pairs (void)
   for (i = 0; alias_pairs && alias_pairs->iterate (i, &p);)
     {
       symtab_node *target_node = symtab_node::get_for_asmname (p->target);
-
+      symtab_node *node = symtab_node::get (p->decl);
+      if (node && TREE_CODE (p->decl) == FUNCTION_DECL
+         && DECL_SAVED_TREE (p->decl))
+       {
+         node->alias = false;
+         alias_pairs->unordered_remove (i);
+         continue;
+       }
       /* Weakrefs with target not defined in current unit are easy to handle:
         they behave just as external variables except we need to note the
         alias flag to later output the weakref pseudo op into asm file.  */
       if (!target_node
          && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL)
        {
-         symtab_node *node = symtab_node::get (p->decl);
          if (node)
            {
              node->alias_target = p->target;
@@ -1426,7 +1432,6 @@ handle_alias_pairs (void)
       else if (!target_node)
        {
          error ("%q+D aliased to undefined symbol %qE", p->decl, p->target);
-         symtab_node *node = symtab_node::get (p->decl);
          if (node)
            node->alias = false;
          alias_pairs->unordered_remove (i);
diff --git a/gcc/testsuite/gcc.dg/attr-alias-6.c 
b/gcc/testsuite/gcc.dg/attr-alias-6.c
new file mode 100644
index 0000000..a3ec311
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/attr-alias-6.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+/* { dg-require-alias "" } */
+static void __attribute__((alias("bar"))) foo(void) { } /* { dg-warning 
"attribute ignored because function is defined" } */
+void bar(void);
diff --git a/gcc/testsuite/gcc.dg/attr-weakref-5.c 
b/gcc/testsuite/gcc.dg/attr-weakref-5.c
new file mode 100644
index 0000000..bb21126
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/attr-weakref-5.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+/* { dg-require-weak "" } */
+static void __attribute__((weakref("bar"))) foo(void) { } /* { dg-warning 
"attribute ignored because function is defined" } */
+void foo(void);
-- 
1.8.3.1

Reply via email to