diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 2378f892a53..6ac9e6f163e 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -11476,7 +11476,19 @@ reopen_tinst_level (struct tinst_level *level) pop_tinst_level (); if (current_tinst_level) current_tinst_level->errors = errorcount+sorrycount; - return level->maybe_get_node (); + + tree decl = level->maybe_get_node (); + if (decl && modules_p ()) + { + /* An instantiation is in module purview only if it had an explicit + instantiation definition in module purview; mark_decl_instantiated uses + set_instantiating_module to set the flag in that case. */ + if (DECL_MODULE_PURVIEW_P (decl)) + module_kind |= MK_PURVIEW; + else + module_kind &= ~MK_PURVIEW; + } + return decl; } /* Returns the TINST_LEVEL which gives the original instantiation @@ -25969,6 +25981,7 @@ mark_decl_instantiated (tree result, int extern_p) { mark_definable (result); mark_needed (result); + set_instantiating_module (result); /* Always make artificials weak. */ if (DECL_ARTIFICIAL (result) && flag_weak) comdat_linkage (result); @@ -27930,6 +27943,7 @@ instantiate_pending_templates (int retries) { int reconsider; location_t saved_loc = input_location; + unsigned saved_module_kind = module_kind; /* Instantiating templates may trigger vtable generation. This in turn may require further template instantiations. We place a limit here @@ -28020,6 +28034,7 @@ instantiate_pending_templates (int retries) while (reconsider); input_location = saved_loc; + module_kind = saved_module_kind; } /* Substitute ARGVEC into T, which is a list of initializers for diff --git a/gcc/testsuite/g++.dg/modules/gmf-3.C b/gcc/testsuite/g++.dg/modules/gmf-3.C new file mode 100644 index 00000000000..6b7ed503669 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/gmf-3.C @@ -0,0 +1,29 @@ +// PR c++/114630 +// { dg-additional-options "-fmodules-ts -Wno-global-module -fdump-lang-module" } +// { dg-module-cmi M } + +module; +template struct allocator { + allocator() {} +}; +template class allocator; + +// Deferred instantiation of GM virtual functions or friend functions +// should not place newly discovered declarations in the module purview. +template +void go() { + extern T fn_decl(); +} +template +struct S { + friend void x() {} + virtual void f() { + go(); + } +}; +inline S s; + +export module M; + +// The whole GMF should be discarded here +// { dg-final { scan-lang-dump "Wrote 0 clusters" module } } diff --git a/gcc/testsuite/g++.dg/modules/gmf-4.C b/gcc/testsuite/g++.dg/modules/gmf-4.C new file mode 100644 index 00000000000..91368f3cdcc --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/gmf-4.C @@ -0,0 +1,13 @@ +// PR c++/114630 +// { dg-additional-options "-fmodules-ts -Wno-global-module -fdump-lang-module" } +// { dg-module-cmi M } + +module; +template struct allocator { + allocator() {} +}; +export module M; +template class allocator; + +// allocator is reachable because the explicit instantiation is in purview. +// { dg-final { scan-lang-dump {Wrote declaration[^\n]*allocator} module } } diff --git a/gcc/testsuite/g++.dg/modules/gmf-xtreme.C b/gcc/testsuite/g++.dg/modules/gmf-xtreme.C new file mode 100644 index 00000000000..0a01c405291 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/gmf-xtreme.C @@ -0,0 +1,10 @@ +// PR c++/114630 +// { dg-additional-options "-fmodules-ts -fdump-lang-module" } +// { dg-module-cmi empty } + +module; +#include "xtreme-header.h" +export module empty; + +// The whole GMF should be discarded here +// { dg-final { scan-lang-dump "Wrote 0 clusters" module } } diff --git a/gcc/testsuite/g++.dg/modules/modules.exp b/gcc/testsuite/g++.dg/modules/modules.exp index 335401b2166..81d0bebdfe5 100644 --- a/gcc/testsuite/g++.dg/modules/modules.exp +++ b/gcc/testsuite/g++.dg/modules/modules.exp @@ -269,6 +269,7 @@ proc module-init { src } { set std_prefix "-std=c++" global extra_tool_flags set extra_tool_flags {} + global MOD_STD_LIST foreach op $tmp { switch [lindex $op 0] { @@ -288,13 +289,16 @@ proc module-init { src } { } } - if { !$have_std } { - global MOD_STD_LIST + if { $have_std } { + lappend option_list "" + } elseif { [string match "*xtreme*" $src] } { + # Only run the xtreme tests once. + set x [lindex $MOD_STD_LIST end] + lappend option_list "${std_prefix}$x" + } else { foreach x $MOD_STD_LIST { lappend option_list "${std_prefix}$x" } - } else { - lappend option_list "" } return $option_list