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
> 
> 

Reply via email to