My patch for PR 91476 worked for decls that are implicitly comdat/weak due
to C++ linkage rules, but broke variables explicitly marked weak.

Tested x86_64-pc-linux-gnu, applying to trunk.

        PR c++/93477
        PR c++/91476
        * decl2.c (copy_linkage): Do copy DECL_ONE_ONLY and DECL_WEAK.
---
 gcc/cp/decl2.c                    |  8 ++++++--
 gcc/testsuite/g++.dg/abi/guard4.C | 11 +++++++++++
 2 files changed, 17 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/abi/guard4.C

diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 1ecf0b937d5..98d8e6a6b53 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -3228,8 +3228,12 @@ copy_linkage (tree guard, tree decl)
     {
       CP_DECL_THREAD_LOCAL_P (guard) = CP_DECL_THREAD_LOCAL_P (decl);
       set_decl_tls_model (guard, DECL_TLS_MODEL (decl));
-      /* We can't rely on DECL_WEAK (decl) or DECL_ONE_ONLY (decl) here, as
-        they may not be set until import_export_decl at EOF.  */
+      if (DECL_ONE_ONLY (decl))
+       make_decl_one_only (guard, cxx_comdat_group (guard));
+      if (TREE_PUBLIC (decl))
+       DECL_WEAK (guard) = DECL_WEAK (decl);
+      /* Also check vague_linkage_p, as DECL_WEAK and DECL_ONE_ONLY might not
+        be set until import_export_decl at EOF.  */
       if (vague_linkage_p (decl))
        comdat_linkage (guard);
       DECL_VISIBILITY (guard) = DECL_VISIBILITY (decl);
diff --git a/gcc/testsuite/g++.dg/abi/guard4.C 
b/gcc/testsuite/g++.dg/abi/guard4.C
new file mode 100644
index 00000000000..537c90524f3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/guard4.C
@@ -0,0 +1,11 @@
+// PR c++/93477
+// { dg-require-weak }
+
+namespace x {
+  struct s {
+    s() {}
+    static int a;
+  };
+  // { dg-final { scan-assembler {.weak[^\n]*_ZGVN1x1bE} } }
+  struct s __attribute__((weak)) b = s();
+}

base-commit: 5aebfb71763c7c8d0bb96adcd0a5f94de96a2a13
-- 
2.18.1

Reply via email to