On Fri, Mar 01, 2024 at 08:18:09AM -0500, Jason Merrill wrote: > On 2/29/24 20:08, Nathaniel Shead wrote: > > Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk? > > > > -- >8 -- > > > > An implicit instantiation has an initializer depending on whether > > DECL_INITIALIZED_P is set (like normal VAR_DECLs) which needs to be > > written to ensure that consumers of header modules properly emit > > definitions for these instantiations. This patch ensures that we > > correctly fallback to checking this flag when DECL_INITIAL is not set > > for a template instantiation. > > Can you say more about how and why DECL_INITIAL and DECL_INITIALIZED_P are > inconsistent here?
For variables with non-trivial dynamic initialization, DECL_INITIAL can be empty after 'split_nonconstant_init' but DECL_INITIALIZED_P is still set; we need to check the latter to determine if we need to go looking for a definition to emit (often in 'static_aggregates' here). This is the case in the linked testcase. However, for template specialisations (not instantiations?) we primarily care about DECL_INITIAL; if the variable has initialization depending on a template parameter then we'll need to emit that definition even though it doesn't yet have DECL_INITIALIZED_P set; this is the case in e.g. template <int N> int value = N; > > As a drive-by fix, also ensures that the count of initializers matches > > the actual number of initializers written. This doesn't seem to be > > necessary for correctness in the current testsuite, but feels wrong and > > makes debugging harder when initializers aren't properly written for > > other reasons. > > > > PR c++/114170 > > > > gcc/cp/ChangeLog: > > > > * module.cc (has_definition): Fall back to DECL_INITIALIZED_P > > when DECL_INITIAL is not set on a template. > > (module_state::write_inits): Only increment count when > > initializers are actually written. > > > > gcc/testsuite/ChangeLog: > > > > * g++.dg/modules/var-tpl-2_a.H: New test. > > * g++.dg/modules/var-tpl-2_b.C: New test. > > > > Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com> > > --- > > gcc/cp/module.cc | 8 +++++--- > > gcc/testsuite/g++.dg/modules/var-tpl-2_a.H | 10 ++++++++++ > > gcc/testsuite/g++.dg/modules/var-tpl-2_b.C | 10 ++++++++++ > > 3 files changed, 25 insertions(+), 3 deletions(-) > > create mode 100644 gcc/testsuite/g++.dg/modules/var-tpl-2_a.H > > create mode 100644 gcc/testsuite/g++.dg/modules/var-tpl-2_b.C > > > > diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc > > index 1b2ba2e0fa8..09578de41ec 100644 > > --- a/gcc/cp/module.cc > > +++ b/gcc/cp/module.cc > > @@ -11586,8 +11586,9 @@ has_definition (tree decl) > > case VAR_DECL: > > if (DECL_LANG_SPECIFIC (decl) > > - && DECL_TEMPLATE_INFO (decl)) > > - return DECL_INITIAL (decl); > > + && DECL_TEMPLATE_INFO (decl) > > + && DECL_INITIAL (decl)) > > + return true; > > else > > { > > if (!DECL_INITIALIZED_P (decl)) > > @@ -17528,13 +17529,14 @@ module_state::write_inits (elf_out *to, > > depset::hash &table, unsigned *crc_ptr) > > tree list = static_aggregates; > > for (int passes = 0; passes != 2; passes++) > > { > > - for (tree init = list; init; init = TREE_CHAIN (init), count++) > > + for (tree init = list; init; init = TREE_CHAIN (init)) > > if (TREE_LANG_FLAG_0 (init)) > > { > > tree decl = TREE_VALUE (init); > > dump ("Initializer:%u for %N", count, decl); > > sec.tree_node (decl); > > + ++count; > > } > > list = tls_aggregates; > > diff --git a/gcc/testsuite/g++.dg/modules/var-tpl-2_a.H > > b/gcc/testsuite/g++.dg/modules/var-tpl-2_a.H > > new file mode 100644 > > index 00000000000..607fc0b808e > > --- /dev/null > > +++ b/gcc/testsuite/g++.dg/modules/var-tpl-2_a.H > > @@ -0,0 +1,10 @@ > > +// PR c++/114170 > > +// { dg-additional-options "-fmodule-header" } > > +// { dg-module-cmi {} } > > + > > +inline int f() { return 42; } > > + > > +template<class> > > +inline int v = f(); > > + > > +inline int g() { return v<int>; } > > diff --git a/gcc/testsuite/g++.dg/modules/var-tpl-2_b.C > > b/gcc/testsuite/g++.dg/modules/var-tpl-2_b.C > > new file mode 100644 > > index 00000000000..6d2ef4004e6 > > --- /dev/null > > +++ b/gcc/testsuite/g++.dg/modules/var-tpl-2_b.C > > @@ -0,0 +1,10 @@ > > +// PR c++/114170 > > +// { dg-module-do run } > > +// { dg-additional-options "-fmodules-ts" } > > + > > +import "var-tpl-2_a.H"; > > + > > +int main() { > > + if (v<int> != 42) > > + __builtin_abort(); > > +} >