Tested on x86_64-pc-linux-gnu (so far just modules.exp), OK for trunk if
full bootstrap+regtest succeeds?
-- >8 --
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]>
---
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(-)
create mode 100644 gcc/testsuite/g++.dg/modules/internal-19_a.C
create mode 100644 gcc/testsuite/g++.dg/modules/internal-19_b.C
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 017bacdf223..e707b7fa415 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -14229,9 +14229,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
@@ -14244,16 +14245,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 00000000000..8b7bb45856c
--- /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 00000000000..58d1fd521b0
--- /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);
+}
--
2.51.0