On Fri, 20 Mar 2026, Nathaniel Shead wrote:

> Bootstrapped and regtested (so far just modules.exp) on
> x86_64-pc-linux-gnu.  Does this seem like a reasonable change to make?
> 
> -- >8 --
> 
> 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.

Agreed.  This is OK by me, thanks a lot!

> 
>       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]>
> ---
>  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(-)
>  create mode 100644 gcc/testsuite/g++.dg/modules/using-34_a.C
>  create mode 100644 gcc/testsuite/g++.dg/modules/using-34_b.C
> 
> diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
> index 83d24a3267d..8ee15f41aeb 100644
> --- a/gcc/cp/module.cc
> +++ b/gcc/cp/module.cc
> @@ -14494,7 +14494,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");
>  
> @@ -14934,7 +14934,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.  */
> @@ -15960,6 +15961,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 13aafab4e68..5a642e48851 100644
> --- a/gcc/cp/name-lookup.cc
> +++ b/gcc/cp/name-lookup.cc
> @@ -5480,18 +5480,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 00f470a0d5d..f1d1769ef07 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -4895,7 +4895,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 00000000000..ac4994372ca
> --- /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 00000000000..bb829832ebc
> --- /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-error=expose-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;
> +}
> -- 
> 2.51.0
> 
> 

Reply via email to