https://gcc.gnu.org/g:8b9a294a484ed50ee36cb435dc089a78df385f5c

commit r16-8488-g8b9a294a484ed50ee36cb435dc089a78df385f5c
Author: Nathaniel Shead <[email protected]>
Date:   Thu Mar 19 23:58:30 2026 +1100

    c++/modules: Allow exporting usings of internal GMF entities with pedwarn 
[PR124268]
    
    As discussed in libstdc++/124268, the std module relies on exporting
    using-declarations for various entities, but on some targets the
    relevant declarations have internal linkage.
    
    Given we already support exposures of such internal linkage entities for
    migration purposes, it seems reasonable to allow the same for
    using-declarations.
    
            PR libstdc++/124268
    
    gcc/ChangeLog:
    
            * doc/invoke.texi: Note that -Wexpose-global-module-tu-local
            also applies to 'export using' declarations.
    
    gcc/cp/ChangeLog:
    
            * module.cc (instantiating_tu_local_entity): Use pedwarn instead
            of warning.
            (depset::hash::add_binding_entity): Don't skip exported
            using-decls as TU-local entities.
            (depset::hash::finalize_dependencies): Don't attempt to complain
            again about using-decls referencing TU-local entities.
            * name-lookup.cc (check_can_export_using_decl): Demote the error
            to a warning for using-decls of GMF vars or functions.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/modules/using-34_a.C: New test.
            * g++.dg/modules/using-34_b.C: New test.
    
    Signed-off-by: Nathaniel Shead <[email protected]>
    Reviewed-by: Patrick Palka <[email protected]>
    Reviewed-by: Jason Merrill <[email protected]>

Diff:
---
 gcc/cp/module.cc                          | 10 +++++--
 gcc/cp/name-lookup.cc                     | 46 +++++++++++++++++++++++--------
 gcc/doc/invoke.texi                       |  3 +-
 gcc/testsuite/g++.dg/modules/using-34_a.C | 15 ++++++++++
 gcc/testsuite/g++.dg/modules/using-34_b.C | 22 +++++++++++++++
 5 files changed, 82 insertions(+), 14 deletions(-)

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 1757bd58f772..e5547f7d029f 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -14531,7 +14531,7 @@ instantiating_tu_local_entity (tree decl)
     return false;
 
   auto_diagnostic_group d;
-  warning (OPT_Wexpose_global_module_tu_local,
+  pedwarn (input_location, OPT_Wexpose_global_module_tu_local,
           "instantiation exposes TU-local entity %qD", decl);
   inform (DECL_SOURCE_LOCATION (decl), "declared here");
 
@@ -14972,7 +14972,8 @@ depset::hash::add_binding_entity (tree decl, WMB_Flags 
flags, void *data_)
        return false;
 
       bool internal_decl = false;
-      if (!header_module_p () && is_tu_local_entity (decl))
+      if (!header_module_p () && is_tu_local_entity (decl)
+         && !((flags & WMB_Using) && (flags & WMB_Export)))
        {
          /* A TU-local entity.  For ADL we still need to create bindings
             for internal-linkage functions attached to a named module.  */
@@ -15998,6 +15999,11 @@ depset::hash::finalize_dependencies ()
       if (dep->is_tu_local ())
        continue;
 
+      /* We already complained about usings of non-external entities in
+        check_can_export_using_decl, don't do it again here.  */
+      if (dep->get_entity_kind () == EK_USING)
+       continue;
+
       if (dep->is_exposure ())
        {
          bool explained = diagnose_bad_internal_ref (dep);
diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc
index c0f48b5496dc..2127cf999370 100644
--- a/gcc/cp/name-lookup.cc
+++ b/gcc/cp/name-lookup.cc
@@ -5496,18 +5496,42 @@ check_can_export_using_decl (tree binding)
          && !DECL_MODULE_EXPORT_P (not_tmpl)))
     {
       auto_diagnostic_group d;
-      error ("exporting %q#D that does not have external linkage",
-            binding);
-      if (linkage == lk_none)
-       inform (DECL_SOURCE_LOCATION (entity),
-               "%q#D declared here with no linkage", entity);
-      else if (linkage == lk_internal)
-       inform (DECL_SOURCE_LOCATION (entity),
-               "%q#D declared here with internal linkage", entity);
+      bool diag = true;
+
+      /* As an extension, we'll allow exposing internal entities from
+        the GMF, to aid in migration to modules.  For now, we only
+        support this for functions and variables; see also 
+        depset::is_tu_local.  */
+      bool relaxed = (VAR_OR_FUNCTION_DECL_P (not_tmpl)
+                     && !(DECL_LANG_SPECIFIC (not_tmpl)
+                          && DECL_MODULE_PURVIEW_P (not_tmpl)));
+      if (relaxed)
+       {
+         gcc_checking_assert (linkage != lk_external);
+         diag = (warning_enabled_at (DECL_SOURCE_LOCATION (entity),
+                                     OPT_Wexpose_global_module_tu_local)
+                 && pedwarn (input_location,
+                             OPT_Wexpose_global_module_tu_local,
+                             "exporting %q#D that does not have "
+                             "external linkage", binding));
+       }
       else
-       inform (DECL_SOURCE_LOCATION (entity),
-               "%q#D declared here with module linkage", entity);
-      return false;
+       error ("exporting %q#D that does not have external linkage", binding);
+
+      if (diag)
+       {
+         if (linkage == lk_none)
+           inform (DECL_SOURCE_LOCATION (entity),
+                   "%q#D declared here with no linkage", entity);
+         else if (linkage == lk_internal)
+           inform (DECL_SOURCE_LOCATION (entity),
+                   "%q#D declared here with internal linkage", entity);
+         else
+           inform (DECL_SOURCE_LOCATION (entity),
+                   "%q#D declared here with module linkage", entity);
+       }
+
+      return relaxed;
     }
 
   return true;
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 4b208344398d..b01787d29fc8 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -4898,7 +4898,8 @@ As an extension, GCC allows exposures of internal 
variables and functions that
 were declared in the global module fragment.  This warning indicates when such
 an invalid exposure has occurred, and can be silenced using diagnostic pragmas
 either at the site of the exposure, or at the point of declaration of the
-internal declaration.
+internal declaration.  This also applies to @code{export using} declarations
+naming such entities.
 
 When combined with @option{-Wtemplate-names-tu-local}, GCC will also warn about
 non-exposure references to TU-local entities in template bodies. Such templates
diff --git a/gcc/testsuite/g++.dg/modules/using-34_a.C 
b/gcc/testsuite/g++.dg/modules/using-34_a.C
new file mode 100644
index 000000000000..ac4994372cae
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/using-34_a.C
@@ -0,0 +1,15 @@
+// PR libstdc++/124268
+// { dg-additional-options "-fmodules -Wno-global-module 
-Wno-error=expose-global-module-tu-local" }
+// { dg-module-cmi M }
+
+module;
+
+static void f() {} // { dg-message "declared here with internal linkage" }
+static int x;      // { dg-message "declared here with internal linkage" }
+
+export module M;
+
+namespace ns {
+  export using ::f;  // { dg-warning "does not have external linkage" }
+  export using ::x;  // { dg-warning "does not have external linkage" }
+}
diff --git a/gcc/testsuite/g++.dg/modules/using-34_b.C 
b/gcc/testsuite/g++.dg/modules/using-34_b.C
new file mode 100644
index 000000000000..e6b2f1d48c3e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/using-34_b.C
@@ -0,0 +1,22 @@
+// PR libstdc++/124268
+// { dg-additional-options "-fmodules -Wno-global-module 
-Wno-global-module-tu-local" }
+// { dg-module-cmi !K }
+
+module;
+
+// Non vars/functions cannot escape, even when relaxed.
+namespace { struct Internal; };  // { dg-message "declared here with internal 
linkage" }
+struct {} none;                         // { dg-message "declared here with no 
linkage" }
+using NoneType = decltype(none);
+
+export module K;
+import M;
+
+export using ::Internal;  // { dg-error "does not have external linkage" }
+export using ::NoneType;  // { dg-error "does not have external linkage" }
+
+// OK
+int test() {
+  ns::f();
+  return ns::x;
+}

Reply via email to