re PR c++/20961 (ICE on pragma weak/__attribute__((weak)))
authorJakub Jelinek <jakub@redhat.com>
Fri, 6 May 2005 09:16:24 +0000 (11:16 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 6 May 2005 09:16:24 +0000 (11:16 +0200)
PR c++/20961
* varasm.c (merge_weak): Remove NEWDECL from WEAK_DECLS chain
if both NEWDECL and OLDDECL are already weak.

* g++.dg/ext/weak3.C: New test.

From-SVN: r99306

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/weak3.C [new file with mode: 0644]
gcc/varasm.c

index 1f163c3..4fed688 100644 (file)
@@ -1,3 +1,9 @@
+2005-05-06  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/20961
+       * varasm.c (merge_weak): Remove NEWDECL from WEAK_DECLS chain
+       if both NEWDECL and OLDDECL are already weak.
+
 2005-05-06  Richard Sandiford  <rsandifo@redhat.com>
 
        * config/rs6000/sysv4.h (EXTRA_SUBTARGET_SWITCHES): Delete.
index c981cee..ae84155 100644 (file)
@@ -1,3 +1,8 @@
+2005-05-06  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/20961
+       * g++.dg/ext/weak3.C: New test.
+
 2005-05-05  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/21352
diff --git a/gcc/testsuite/g++.dg/ext/weak3.C b/gcc/testsuite/g++.dg/ext/weak3.C
new file mode 100644 (file)
index 0000000..360821a
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/20961
+// Test for #pragma weak and __attribute__((weak)) being used together. 
+// { dg-do compile }
+// { dg-require-weak "" }
+// { dg-options "" }
+
+// { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?_Z3foov" } }
+
+int foo ();
+#pragma weak foo
+
+int
+__attribute__((weak))
+foo ()
+{
+  return 0;
+}
index f0799e1..6f6a817 100644 (file)
@@ -4303,7 +4303,21 @@ void
 merge_weak (tree newdecl, tree olddecl)
 {
   if (DECL_WEAK (newdecl) == DECL_WEAK (olddecl))
-    return;
+    {
+      if (DECL_WEAK (newdecl) && SUPPORTS_WEAK)
+        {
+          tree *pwd;
+          /* We put the NEWDECL on the weak_decls list at some point
+             and OLDDECL as well.  Keep just OLDDECL on the list.  */
+         for (pwd = &weak_decls; *pwd; pwd = &TREE_CHAIN (*pwd))
+           if (TREE_VALUE (*pwd) == newdecl)
+             {
+               *pwd = TREE_CHAIN (*pwd);
+               break;
+             }
+        }
+      return;
+    }
 
   if (DECL_WEAK (newdecl))
     {