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.
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