c++/modules: Handle importing an undeduced auto over a deduced auto [PR124735]
Checks
| Context |
Check |
Description |
| linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 |
success
|
Test passed
|
| linaro-tcwg-bot/tcwg_gcc_build--master-arm |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_gcc_check--master-arm |
success
|
Test passed
|
Commit Message
Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk/15?
-- >8 --
Like with implicit constexpr, we need to handle cases where we import an
function declaration with undeduced auto, but we already have a
definition available with deduced auto. In this case we can just keep
the existing declaration's type.
PR c++/124735
gcc/cp/ChangeLog:
* module.cc (trees_in::is_matching_decl): Handle importing
undeduced auto when existing is already deduced.
gcc/testsuite/ChangeLog:
* g++.dg/modules/auto-8_a.H: New test.
* g++.dg/modules/auto-8_b.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
---
gcc/cp/module.cc | 6 +++++-
gcc/testsuite/g++.dg/modules/auto-8_a.H | 7 +++++++
gcc/testsuite/g++.dg/modules/auto-8_b.C | 15 +++++++++++++++
3 files changed, 27 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/g++.dg/modules/auto-8_a.H
create mode 100644 gcc/testsuite/g++.dg/modules/auto-8_b.C
Comments
On 4/4/26 9:13 AM, Nathaniel Shead wrote:
> Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk/15?
OK.
> -- >8 --
>
> Like with implicit constexpr, we need to handle cases where we import an
> function declaration with undeduced auto, but we already have a
> definition available with deduced auto. In this case we can just keep
> the existing declaration's type.
>
> PR c++/124735
>
> gcc/cp/ChangeLog:
>
> * module.cc (trees_in::is_matching_decl): Handle importing
> undeduced auto when existing is already deduced.
>
> gcc/testsuite/ChangeLog:
>
> * g++.dg/modules/auto-8_a.H: New test.
> * g++.dg/modules/auto-8_b.C: New test.
>
> Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
> ---
> gcc/cp/module.cc | 6 +++++-
> gcc/testsuite/g++.dg/modules/auto-8_a.H | 7 +++++++
> gcc/testsuite/g++.dg/modules/auto-8_b.C | 15 +++++++++++++++
> 3 files changed, 27 insertions(+), 1 deletion(-)
> create mode 100644 gcc/testsuite/g++.dg/modules/auto-8_a.H
> create mode 100644 gcc/testsuite/g++.dg/modules/auto-8_b.C
>
> diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
> index 6958388e454..25ffbd9eb5a 100644
> --- a/gcc/cp/module.cc
> +++ b/gcc/cp/module.cc
> @@ -12650,7 +12650,9 @@ trees_in::is_matching_decl (tree existing, tree decl, bool is_typedef)
>
> /* Similarly if EXISTING has an undeduced return type, but DECL's
> is already deduced. */
> - if (undeduced_auto_decl (existing) && !undeduced_auto_decl (decl))
> + bool e_undeduced = undeduced_auto_decl (existing);
> + bool d_undeduced = undeduced_auto_decl (decl);
> + if (e_undeduced && !d_undeduced)
> {
> dump (dumper::MERGE)
> && dump ("Propagating deduced return type to %N", existing);
> @@ -12659,6 +12661,8 @@ trees_in::is_matching_decl (tree existing, tree decl, bool is_typedef)
> DECL_SAVED_AUTO_RETURN_TYPE (existing) = TREE_TYPE (e_type);
> TREE_TYPE (existing) = change_return_type (TREE_TYPE (d_type), e_type);
> }
> + else if (d_undeduced && !e_undeduced)
> + /* EXISTING was deduced, leave it alone. */;
> else if (type_uses_auto (d_ret)
> && !same_type_p (TREE_TYPE (d_type), TREE_TYPE (e_type)))
> {
> diff --git a/gcc/testsuite/g++.dg/modules/auto-8_a.H b/gcc/testsuite/g++.dg/modules/auto-8_a.H
> new file mode 100644
> index 00000000000..a0a5cacd995
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/modules/auto-8_a.H
> @@ -0,0 +1,7 @@
> +// PR c++/124735
> +// { dg-additional-options "-fmodule-header" }
> +// { dg-module-cmi {} }
> +
> +struct S {
> + auto foo();
> +};
> diff --git a/gcc/testsuite/g++.dg/modules/auto-8_b.C b/gcc/testsuite/g++.dg/modules/auto-8_b.C
> new file mode 100644
> index 00000000000..bd749228a04
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/modules/auto-8_b.C
> @@ -0,0 +1,15 @@
> +// PR c++/124735
> +// { dg-additional-options "-fmodules" }
> +
> +struct S {
> + auto foo();
> +};
> +
> +auto S::foo() { return 123; }
> +auto pfn = &S::foo;
> +
> +import "auto-8_a.H";
> +
> +int main() {
> + return S{}.foo() != 123;
> +}
@@ -12650,7 +12650,9 @@ trees_in::is_matching_decl (tree existing, tree decl, bool is_typedef)
/* Similarly if EXISTING has an undeduced return type, but DECL's
is already deduced. */
- if (undeduced_auto_decl (existing) && !undeduced_auto_decl (decl))
+ bool e_undeduced = undeduced_auto_decl (existing);
+ bool d_undeduced = undeduced_auto_decl (decl);
+ if (e_undeduced && !d_undeduced)
{
dump (dumper::MERGE)
&& dump ("Propagating deduced return type to %N", existing);
@@ -12659,6 +12661,8 @@ trees_in::is_matching_decl (tree existing, tree decl, bool is_typedef)
DECL_SAVED_AUTO_RETURN_TYPE (existing) = TREE_TYPE (e_type);
TREE_TYPE (existing) = change_return_type (TREE_TYPE (d_type), e_type);
}
+ else if (d_undeduced && !e_undeduced)
+ /* EXISTING was deduced, leave it alone. */;
else if (type_uses_auto (d_ret)
&& !same_type_p (TREE_TYPE (d_type), TREE_TYPE (e_type)))
{
new file mode 100644
@@ -0,0 +1,7 @@
+// PR c++/124735
+// { dg-additional-options "-fmodule-header" }
+// { dg-module-cmi {} }
+
+struct S {
+ auto foo();
+};
new file mode 100644
@@ -0,0 +1,15 @@
+// PR c++/124735
+// { dg-additional-options "-fmodules" }
+
+struct S {
+ auto foo();
+};
+
+auto S::foo() { return 123; }
+auto pfn = &S::foo;
+
+import "auto-8_a.H";
+
+int main() {
+ return S{}.foo() != 123;
+}