On Wed, 3 Jan 2024, Nathaniel Shead wrote: > Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk? > > -- >8 -- > > The attached testcase Patrick found in PR c++/112899 ICEs because it is > attempting to write a variable initializer that is no longer in the > static_aggregates map. > > The issue is that, for non-header modules, the loop in > c_parse_final_cleanups prunes the static_aggregates list, which means > that by the time we get to emitting module information those > initialisers have been lost. > > However, we don't actually need to write non-trivial initialisers for > non-header modules, because they've already been emitted as part of the > module TU itself. Instead let's just only write the initializers from > header modules (which skipped writing them in c_parse_final_cleanups).
Makes sense to me. It seems this may also fix PR103994 where we ICE in the same spot when streaming out an initializer from the global module fragment. > > gcc/cp/ChangeLog: > > * module.cc (trees_out::write_var_def): Only write initializers > in header modules. > > gcc/testsuite/ChangeLog: > > * g++.dg/modules/init-5_a.C: New test. > * g++.dg/modules/init-5_b.C: New test. > > Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com> > --- > gcc/cp/module.cc | 3 ++- > gcc/testsuite/g++.dg/modules/init-5_a.C | 9 +++++++++ > gcc/testsuite/g++.dg/modules/init-5_b.C | 10 ++++++++++ > 3 files changed, 21 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/g++.dg/modules/init-5_a.C > create mode 100644 gcc/testsuite/g++.dg/modules/init-5_b.C > > diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc > index 14818131a70..82b61a2c2ad 100644 > --- a/gcc/cp/module.cc > +++ b/gcc/cp/module.cc > @@ -11707,7 +11707,8 @@ trees_out::write_var_def (tree decl) > { > tree dyn_init = NULL_TREE; > > - if (DECL_NONTRIVIALLY_INITIALIZED_P (decl)) > + /* We only need to write initializers in header modules. */ > + if (header_module_p () && DECL_NONTRIVIALLY_INITIALIZED_P (decl)) > { > dyn_init = value_member (decl, > CP_DECL_THREAD_LOCAL_P (decl) > diff --git a/gcc/testsuite/g++.dg/modules/init-5_a.C > b/gcc/testsuite/g++.dg/modules/init-5_a.C > new file mode 100644 > index 00000000000..466b120b5a0 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/modules/init-5_a.C > @@ -0,0 +1,9 @@ > +// { dg-additional-options "-fmodules-ts" } > +// { dg-module-cmi M } > + > +export module M; > + > +export struct A { > + static int f() { return -1; } > + static inline int x = f(); > +}; > diff --git a/gcc/testsuite/g++.dg/modules/init-5_b.C > b/gcc/testsuite/g++.dg/modules/init-5_b.C > new file mode 100644 > index 00000000000..40973cc6936 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/modules/init-5_b.C > @@ -0,0 +1,10 @@ > +// { dg-module-do run } > +// { dg-additional-options "-fmodules-ts" } > + > +import M; > + > +int main() { > + const int& x = A::x; > + if (x != -1) > + __builtin_abort(); > +} > -- > 2.43.0 > >