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");
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. */
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);
&& !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;
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
--- /dev/null
+// 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;
+}