On Thu, 31 Jul 2025, Nathaniel Shead wrote: > Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk? > And maybe 15?
Good catch re the invisiref handling! This LGTM, Jason what do you think? > > -- >8 -- > > When we merge a function definition, if there already exists a forward > declaration in the importing TU we use the PARM_DECLs belonging to that > decl. This usually works fine, except as noted in the linked PR there > are some flags (such as TREE_ADDRESSABLE) that only get set on a > PARM_DECL once a definition is provided. > > This patch fixes the wrong-code issues by propagating any properties on > PARM_DECLs I could find that may affect codegen. > > PR c++/121238 > > gcc/cp/ChangeLog: > > * module.cc (trees_in::fn_parms_fini): Merge properties for > definitions. > > gcc/testsuite/ChangeLog: > > * g++.dg/modules/merge-19.h: New test. > * g++.dg/modules/merge-19_a.H: New test. > * g++.dg/modules/merge-19_b.C: New test. > > Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com> > --- > gcc/cp/module.cc | 11 +++++++++++ > gcc/testsuite/g++.dg/modules/merge-19.h | 21 +++++++++++++++++++++ > gcc/testsuite/g++.dg/modules/merge-19_a.H | 5 +++++ > gcc/testsuite/g++.dg/modules/merge-19_b.C | 16 ++++++++++++++++ > 4 files changed, 53 insertions(+) > create mode 100644 gcc/testsuite/g++.dg/modules/merge-19.h > create mode 100644 gcc/testsuite/g++.dg/modules/merge-19_a.H > create mode 100644 gcc/testsuite/g++.dg/modules/merge-19_b.C > > diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc > index 2f6a8ab98fa..07a1dd85207 100644 > --- a/gcc/cp/module.cc > +++ b/gcc/cp/module.cc > @@ -11164,6 +11164,17 @@ trees_in::fn_parms_fini (int tag, tree fn, tree > existing, bool is_defn) > names of the parms from us. */ > DECL_NAME (existing_parm) = DECL_NAME (parm); > DECL_SOURCE_LOCATION (existing_parm) = DECL_SOURCE_LOCATION > (parm); > + > + /* And some other flags important for codegen only set on > + a parameter definition. */ > + TREE_ADDRESSABLE (existing_parm) = TREE_ADDRESSABLE (parm); > + DECL_NONLOCAL (existing_parm) = DECL_NONLOCAL (parm); > + DECL_ARG_TYPE (existing_parm) = DECL_ARG_TYPE (parm); > + DECL_BY_REFERENCE (existing_parm) = DECL_BY_REFERENCE (parm); > + > + /* Invisref parms had their types adjusted by cp_genericize. */ > + TREE_TYPE (existing_parm) = TREE_TYPE (parm); > + relayout_decl (existing_parm); > } > > back_refs[~tag] = existing_parm; > diff --git a/gcc/testsuite/g++.dg/modules/merge-19.h > b/gcc/testsuite/g++.dg/modules/merge-19.h > new file mode 100644 > index 00000000000..c3faadce07a > --- /dev/null > +++ b/gcc/testsuite/g++.dg/modules/merge-19.h > @@ -0,0 +1,21 @@ > +// PR c++/121238 > + > +inline void inc(const char*& __first) { > + ++__first; > +} > + > +template <typename = void> > +bool parse_integer(const char *first) { > + const char *start = first; > + inc(first); > + return first != start; > +} > +template bool parse_integer<void>(const char*); > + > + > +struct S { ~S() {} int x; }; > +template <typename = void> > +bool take_by_invisiref(S s) { > + return s.x == 5; > +} > +template bool take_by_invisiref<void>(S); > diff --git a/gcc/testsuite/g++.dg/modules/merge-19_a.H > b/gcc/testsuite/g++.dg/modules/merge-19_a.H > new file mode 100644 > index 00000000000..149a447f266 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/modules/merge-19_a.H > @@ -0,0 +1,5 @@ > +// PR c++/121238 > +// { dg-additional-options "-fmodule-header" } > +// { dg-module-cmi {} } > + > +#include "merge-19.h" > diff --git a/gcc/testsuite/g++.dg/modules/merge-19_b.C > b/gcc/testsuite/g++.dg/modules/merge-19_b.C > new file mode 100644 > index 00000000000..345e7fe1342 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/modules/merge-19_b.C > @@ -0,0 +1,16 @@ > +// PR c++/121238 > +// { dg-module-do run } > +// { dg-additional-options "-fmodules -fno-module-lazy" } > + > +#include "merge-19.h" > +import "merge-19_a.H"; > + > +int main() { > + const char fmt[] = "5"; > + if (!parse_integer<void>(fmt)) > + __builtin_abort(); > + > + S s{ 5 }; > + if (!take_by_invisiref(s)) > + __builtin_abort(); > +} > -- > 2.47.0 > >