From: Nathaniel Shead Date: Sat, 15 Nov 2025 04:11:55 +0000 (+1100) Subject: c++/modules: Keep tracking instantiations of static class variable templates [PR122625] X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4711901000ab141dbf3995ec4541f9d9a2351472;p=thirdparty%2Fgcc.git c++/modules: Keep tracking instantiations of static class variable templates [PR122625] r16-4930-gfd5c057c2d01 ensured that we noted all class-scope variables. But I also added a clause to 'read_var_def' to skip all class-scope instantiations, under the mistaken belief that this would be handled in read_class_def. But as the testcase shows, read_class_def cannot (and should not) register instantiations of member variable templates, as when reading the class it just sees the template declaration. So this patch re-enables tracking instantiations of class-scope variable templates. PR c++/122625 gcc/cp/ChangeLog: * module.cc (trees_in::read_var_def): Also track class-scope primary template specialisations. gcc/testsuite/ChangeLog: * g++.dg/modules/inst-7_a.C: New test. * g++.dg/modules/inst-7_b.C: New test. Signed-off-by: Nathaniel Shead Reviewed-by: Jason Merrill --- diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 48ee7d1e790..017bacdf223 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -13074,8 +13074,10 @@ trees_in::read_var_def (tree decl, tree maybe_template) if (DECL_EXPLICIT_INSTANTIATION (decl) && !DECL_EXTERNAL (decl)) setup_explicit_instantiation_definition_linkage (decl); - /* Class static data members are handled in read_class_def. */ - if (!DECL_CLASS_SCOPE_P (decl) + /* Class non-template static members are handled in read_class_def. + But still handle specialisations of member templates. */ + if ((!DECL_CLASS_SCOPE_P (decl) + || primary_template_specialization_p (decl)) && (DECL_IMPLICIT_INSTANTIATION (decl) || (DECL_EXPLICIT_INSTANTIATION (decl) && !DECL_EXTERNAL (decl)))) diff --git a/gcc/testsuite/g++.dg/modules/inst-7_a.C b/gcc/testsuite/g++.dg/modules/inst-7_a.C new file mode 100644 index 00000000000..7489edfa252 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/inst-7_a.C @@ -0,0 +1,33 @@ +// PR c++/122625 +// { dg-additional-options "-fmodules" } +// { dg-module-cmi M } + +export module M; +struct integral_constant { + void f() const {} +}; +struct span { + template static constexpr integral_constant __v{}; + template static constexpr integral_constant partial{}; +}; +template constexpr integral_constant span::partial{}; + +template +struct nested { + template static const U arr[3]; +}; +template +struct nested { + template static const U arr[3]; +}; +template template const U nested::arr[3] = {}; +template template const U nested::arr[3] = {}; +template template const U nested::arr[3] = {}; + +export inline void format() { + span::__v<1>.f(); + span::partial<5, 0>.f(); + nested::arr[0].f(); + nested::arr[0].f(); + nested::arr[0].f(); +} diff --git a/gcc/testsuite/g++.dg/modules/inst-7_b.C b/gcc/testsuite/g++.dg/modules/inst-7_b.C new file mode 100644 index 00000000000..3a49b516bea --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/inst-7_b.C @@ -0,0 +1,13 @@ +// PR c++/122625 +// { dg-additional-options "-fmodules" } + +import M; +int main() { + format(); +} + +// { dg-final { scan-assembler {_ZNW1M4span3__vILi1EEE:} } } +// { dg-final { scan-assembler {_ZNW1M4span7partialILi5ELi0EEE:} } } +// { dg-final { scan-assembler {_ZNW1M6nestedIiE3arrIS_17integral_constantEE:} } } +// { dg-final { scan-assembler {_ZNW1M6nestedIPiE3arrIS_17integral_constantEE:} } } +// { dg-final { scan-assembler {_ZNW1M6nestedIPiE3arrIPS_17integral_constantEE:} } }