On Tue, 23 Apr 2024, Patrick Palka wrote: > Tested on x86_64-pc-linux-gnu, does this look OK for trunk? > > -- >8 -- > > When merging an imported function template specialization with an > existing one, if the existing one has an undeduced return type and the > imported one's is already deduced, we need to propagate the deduced type > since once we install the imported definition we won't get a chance to > deduce it by normal means. > > This patch makes is_matching_decl propagate the deduced return type > alongside the existing propagate of the existing specification. I
er, "alongside the existing propagation of the exception specification". > suppose could instead propagate it later when installing the imported > definition from read_definition, but it seems best to propagate it > sooner rather than later. > > PR c++/114795 > > gcc/cp/ChangeLog: > > * module.cc (trees_in::is_matching_decl): Propagate deduced > function return type. > > gcc/testsuite/ChangeLog: > > * g++.dg/modules/auto-4_a.H: New test. > * g++.dg/modules/auto-4_b.C: New test. > --- > gcc/cp/module.cc | 5 +++++ > gcc/testsuite/g++.dg/modules/auto-4_a.H | 14 ++++++++++++++ > gcc/testsuite/g++.dg/modules/auto-4_b.C | 15 +++++++++++++++ > 3 files changed, 34 insertions(+) > create mode 100644 gcc/testsuite/g++.dg/modules/auto-4_a.H > create mode 100644 gcc/testsuite/g++.dg/modules/auto-4_b.C > > diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc > index d94d8ff4df9..e10e19ac9f7 100644 > --- a/gcc/cp/module.cc > +++ b/gcc/cp/module.cc > @@ -11537,6 +11537,11 @@ trees_in::is_matching_decl (tree existing, tree > decl, bool is_typedef) > else if (!DEFERRED_NOEXCEPT_SPEC_P (d_spec) > && !comp_except_specs (d_spec, e_spec, ce_type)) > goto mismatch; > + > + /* Similarly if EXISTING has an undeduced return type, but DECL's > + is already deduced. */ > + if (undeduced_auto_decl (existing) && !undeduced_auto_decl (decl)) > + TREE_TYPE (existing) = change_return_type (TREE_TYPE (d_type), e_type); > } > else if (is_typedef) > { > diff --git a/gcc/testsuite/g++.dg/modules/auto-4_a.H > b/gcc/testsuite/g++.dg/modules/auto-4_a.H > new file mode 100644 > index 00000000000..52b50533982 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/modules/auto-4_a.H > @@ -0,0 +1,14 @@ > +// PR c++/114795 > +// { dg-additional-options "-fmodule-header" } > +// { dg-module-cmi {} } > + > +template<class T> > +struct A { > + auto f() { return 0; } Oops, this should be "return T();" to match the other definition below. > +}; > + > +template<class T> > +inline void g() { > + A<int> a; > + a.f(); > +} > diff --git a/gcc/testsuite/g++.dg/modules/auto-4_b.C > b/gcc/testsuite/g++.dg/modules/auto-4_b.C > new file mode 100644 > index 00000000000..378684ef6d0 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/modules/auto-4_b.C > @@ -0,0 +1,15 @@ > +// PR c++/114795 > +// { dg-additional-options "-fmodules-ts -fno-module-lazy" } > + > +template<class T> > +struct A { > + auto f() { return T(); } > +}; > + > +A<int> a; > + > +import "auto-4_a.H"; > + > +int main() { > + g<int>(); // { dg-bogus "before deduction of 'auto'" "" { target *-*-* } 0 > } > +} > -- > 2.45.0.rc0 > >