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);
+}

Reply via email to