On 9/23/24 7:43 PM, Nathaniel Shead wrote:
This patch intends no change in functionality apart from the mangling
difference noted; more tests are in patch 4 of this series, which adds a
way to actually check what the linkage of decl_linkage provides more
directly.

Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?

-- >8 --

Currently modules code uses a variety of ad-hoc methods to attempt to
determine whether an entity has internal linkage, which leads to
inconsistencies and some correctness issues as different edge cases are
neglected.  While investigating this I discovered 'decl_linkage', but it
doesn't seem to have been updated to account for the C++11 clarification
that all entities declared in an anonymous namespace are internal.

I'm not convinced that even in C++98 it was intended that e.g. types in
anonymous namespaces should be external, but some tests in the testsuite
rely on this, so for compatibility I restricted those modifications to
C++11 and later.

This should have relatively minimal impact as not much seems to actually
rely on decl_linkage, but does change the mangling of symbols in
anonymous namespaces slightly.  Previously, we had

   namespace {
     int x;  // mangled as '_ZN12_GLOBAL__N_11xE'
     static int y;  // mangled as '_ZN12_GLOBAL__N_1L1yE'
   }

but with this patch the x is now mangled like y (with the extra 'L').
For contrast, Clang currently mangles neither x nor y with the 'L'.
Since this only affects internal-linkage entities I don't believe this
should break ABI in any observable fashion.

gcc/cp/ChangeLog:

        * name-lookup.cc (do_namespace_alias): Propagate TREE_PUBLIC for
        namespace aliases.
        * tree.cc (decl_linkage): Update rules for C++11.

gcc/testsuite/ChangeLog:

        * g++.dg/modules/mod-sym-4.C: Update test to account for
        non-static internal-linkage variables new mangling.

Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com>
---
  gcc/cp/name-lookup.cc                    |  1 +
  gcc/cp/tree.cc                           | 92 +++++++++++++++---------
  gcc/testsuite/g++.dg/modules/mod-sym-4.C |  4 +-
  3 files changed, 60 insertions(+), 37 deletions(-)

diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc
index c7a693e02d5..50e169eca43 100644
--- a/gcc/cp/name-lookup.cc
+++ b/gcc/cp/name-lookup.cc
@@ -6610,6 +6610,7 @@ do_namespace_alias (tree alias, tree name_space)
    DECL_NAMESPACE_ALIAS (alias) = name_space;
    DECL_EXTERNAL (alias) = 1;
    DECL_CONTEXT (alias) = FROB_CONTEXT (current_scope ());
+  TREE_PUBLIC (alias) = TREE_PUBLIC (DECL_CONTEXT (alias));
    set_originating_module (alias);
pushdecl (alias);
diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index f43febed124..28e14295de4 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -5840,7 +5840,7 @@ char_type_p (tree type)
          || same_type_p (type, wchar_type_node));
  }
-/* Returns the kind of linkage associated with the indicated DECL. Th
+/* Returns the kind of linkage associated with the indicated DECL.  The
     value returned is as specified by the language standard; it is
     independent of implementation details regarding template
     instantiation, etc.  For example, it is possible that a declaration
@@ -5857,53 +5857,75 @@ decl_linkage (tree decl)
       linkage first, and then transform that into a concrete
       implementation.  */
- /* Things that don't have names have no linkage. */
-  if (!DECL_NAME (decl))
-    return lk_none;
+  /* An explicit type alias has no linkage.  */
+  if (TREE_CODE (decl) == TYPE_DECL
+      && !DECL_IMPLICIT_TYPEDEF_P (decl)
+      && !DECL_SELF_REFERENCE_P (decl))
+    {
+      /* But this could be a typedef name for linkage purposes, in which
+        case we're interested in the linkage of the main decl.  */

Perhaps we should move is_naming_typedef_decl out of dwarf2out.cc...

Anyway, the patch is OK.

Jason

Reply via email to