On Sat, Nov 15, 2025 at 10:54:55PM +1100, Nathaniel Shead wrote:
> On Sat, Nov 15, 2025 at 10:32:00AM +0530, Jason Merrill wrote:
> > On 11/15/25 9:47 AM, Nathaniel Shead wrote:
> > > Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk and 15?
> > >
> > > -- >8 --
> > >
> > > 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 removes
> > > the constraint from read_var_def.
> > >
> > > This may cause us to note some variables more than once but I think
> > > that's unlikely to be a large problem, and adding more constraints may
> > > hit another case that I'm not thinking of.
> >
> > OK, but I wonder if checking primary_template_specialization_p would help
> > avoid the extras?
>
> Thanks. The following patch instead of the above does seem to work and
> avoid these issues:
>
> diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
> index ccabd640757..2b3a9301b6c 100644
> --- a/gcc/cp/module.cc
> +++ b/gcc/cp/module.cc
> @@ -13062,8 +13062,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))))
>
> I might submit the first patch for trunk and 15 now though, and will do
> some more thorough testing of this (e.g. partial specs) later just for
> 16, if that's OK.
>
Actually found some time to do some more testing and seems to work fine.
Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk/15?
-- >8 --
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 <[email protected]>
Reviewed-by: Jason Merrill <[email protected]>
---
gcc/cp/module.cc | 6 +++--
gcc/testsuite/g++.dg/modules/inst-7_a.C | 33 +++++++++++++++++++++++++
gcc/testsuite/g++.dg/modules/inst-7_b.C | 13 ++++++++++
3 files changed, 50 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/modules/inst-7_a.C
create mode 100644 gcc/testsuite/g++.dg/modules/inst-7_b.C
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index ccabd640757..2b3a9301b6c 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -13062,8 +13062,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 <int> static constexpr integral_constant __v{};
+ template <int, int> static constexpr integral_constant partial{};
+};
+template <int x> constexpr integral_constant span::partial<x, 0>{};
+
+template <typename T>
+struct nested {
+ template <typename U> static const U arr[3];
+};
+template <typename T>
+struct nested<T*> {
+ template <typename U> static const U arr[3];
+};
+template <typename T> template <typename U> const U nested<T>::arr[3] = {};
+template <typename T> template <typename U> const U nested<T*>::arr[3] = {};
+template <typename T> template <typename U> const U nested<T*>::arr<U*>[3] =
{};
+
+export inline void format() {
+ span::__v<1>.f();
+ span::partial<5, 0>.f();
+ nested<int>::arr<integral_constant>[0].f();
+ nested<int*>::arr<integral_constant>[0].f();
+ nested<int*>::arr<integral_constant*>[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:} } }
--
2.51.0