https://gcc.gnu.org/g:fac9e25d6d0b72220c12c424363b76e782f34779
commit r16-5523-gfac9e25d6d0b72220c12c424363b76e782f34779 Author: Nathaniel Shead <[email protected]> Date: Sun Nov 23 00:06:06 2025 +1100 c++/modules: Fix -Wexpose-global-module-tu-local [PR122636] I had mistakenly been checking the importedness of the originating module decl, but this is wrong: really we want to check if the specific decl we're currently instantating came from another module, so just check DECL_MODULE_IMPORT_P on this directly. Also updated slightly since there are cases where we do emit TU-local function or variable templates, albeit unlikely to come up frequently. PR c++/122636 gcc/cp/ChangeLog: * module.cc (instantiating_tu_local_entity): Don't check importingness of originating module decl; also check templates. gcc/testsuite/ChangeLog: * g++.dg/modules/internal-19_a.C: New test. * g++.dg/modules/internal-19_b.C: New test. Signed-off-by: Nathaniel Shead <[email protected]> Reviewed-by: Jason Merrill <[email protected]> Diff: --- gcc/cp/module.cc | 14 +++++++------- gcc/testsuite/g++.dg/modules/internal-19_a.C | 21 +++++++++++++++++++++ gcc/testsuite/g++.dg/modules/internal-19_b.C | 16 ++++++++++++++++ 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 40f592b7a2ff..a78d452ee8a1 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -14234,9 +14234,10 @@ instantiating_tu_local_entity (tree decl) return true; } - /* Currently, only TU-local variables and functions will be emitted - from named modules. */ - if (!VAR_OR_FUNCTION_DECL_P (decl)) + /* Currently, only TU-local variables and functions, or possibly + templates thereof, will be emitted from named modules. */ + tree inner = STRIP_TEMPLATE (decl); + if (!VAR_OR_FUNCTION_DECL_P (inner)) return false; /* From this point we will only be emitting warnings; if we're not @@ -14249,16 +14250,15 @@ instantiating_tu_local_entity (tree decl) if (!is_tu_local_entity (decl)) return false; - tree origin = get_originating_module_decl (decl); - if (!DECL_LANG_SPECIFIC (STRIP_TEMPLATE (origin)) - || !DECL_MODULE_IMPORT_P (STRIP_TEMPLATE (origin))) + if (!DECL_LANG_SPECIFIC (inner) + || !DECL_MODULE_IMPORT_P (inner)) return false; /* Referencing TU-local entities from a header is generally OK. We don't have an easy way to detect if this declaration came from a header via a separate named module, but we can just ignore that case for warning purposes. */ - unsigned index = import_entity_index (origin); + unsigned index = import_entity_index (decl); module_state *mod = import_entity_module (index); if (mod->is_header ()) return false; diff --git a/gcc/testsuite/g++.dg/modules/internal-19_a.C b/gcc/testsuite/g++.dg/modules/internal-19_a.C new file mode 100644 index 000000000000..8b7bb45856c9 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/internal-19_a.C @@ -0,0 +1,21 @@ +// PR c++/122636 +// { dg-additional-options "-fmodules" } +// { dg-module-cmi M } + +export module M; +export template <typename> +struct Foo { + constexpr static inline auto lambda = []{}; + template <typename T = decltype(lambda)> + static void foo(T = lambda) {} +}; + +export template <typename... Types> +struct Type +{ + template <typename T> + auto test(T to) + { + return [to](auto && ...){ return to; }(); + } +}; diff --git a/gcc/testsuite/g++.dg/modules/internal-19_b.C b/gcc/testsuite/g++.dg/modules/internal-19_b.C new file mode 100644 index 000000000000..58d1fd521b0e --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/internal-19_b.C @@ -0,0 +1,16 @@ +// PR c++/122636 +// { dg-additional-options "-fmodules -Werror=expose-global-module-tu-local" } + +import M; +namespace { + struct Bar {}; + void bar() { Foo<Bar>::foo(); } +} + +int main() { + bar(); + + enum class E { }; + Type<E> t; + t.test(0); +}
