c++: Fix guard variable and attribute weak.
authorJason Merrill <jason@redhat.com>
Tue, 28 Jan 2020 20:15:20 +0000 (15:15 -0500)
committerJason Merrill <jason@redhat.com>
Tue, 28 Jan 2020 21:45:22 +0000 (16:45 -0500)
My patch for PR 91476 worked for decls that are implicitly comdat/weak due
to C++ linkage rules, but broke variables explicitly marked weak.

PR c++/93477
PR c++/91476
* decl2.c (copy_linkage): Do copy DECL_ONE_ONLY and DECL_WEAK.

gcc/cp/ChangeLog
gcc/cp/decl2.c
gcc/testsuite/g++.dg/abi/guard4.C [new file with mode: 0644]

index a110efe90c02e9a91740328d1a262287fddd854e..0a959bbd49d0f30c896d127b9ea446f5035fc526 100644 (file)
@@ -1,5 +1,9 @@
 2020-01-28  Jason Merrill  <jason@redhat.com>
 
+       PR c++/93477
+       PR c++/91476
+       * decl2.c (copy_linkage): Do copy DECL_ONE_ONLY and DECL_WEAK.
+
        PR c++/90546
        * call.c (build_user_type_conversion_1): Allow a template conversion
        returning an rvalue reference to bind directly to an lvalue.
index 1ecf0b937d533dccfbf1614d979fc74786688e89..98d8e6a6b53f998a66e6352d58d5529cfc98b28e 100644 (file)
@@ -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 (file)
index 0000000..537c905
--- /dev/null
@@ -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();
+}