From: Nathaniel Shead Date: Wed, 30 Jul 2025 22:56:09 +0000 (+1000) Subject: c++/modules: Merge PARM_DECL properties from function definitions [PR121238] X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=16e8d1479f60ea22ba604ac4217d5745c7c80b98;p=thirdparty%2Fgcc.git c++/modules: Merge PARM_DECL properties from function definitions [PR121238] 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 Reviewed-by: Jason Merrill Reviewed-by: Patrick Palka (cherry picked from commit 70136bdc76ae1774162ccbeeedd33aa531950e68) --- diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 46d3a3fc14e..0aa2992cf5b 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -11015,6 +11015,20 @@ 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 are only set + by the definition. */ + TREE_ADDRESSABLE (existing_parm) = TREE_ADDRESSABLE (parm); + DECL_BY_REFERENCE (existing_parm) = DECL_BY_REFERENCE (parm); + DECL_NONLOCAL (existing_parm) = DECL_NONLOCAL (parm); + DECL_ARG_TYPE (existing_parm) = DECL_ARG_TYPE (parm); + + /* Invisiref parms had their types adjusted by cp_genericize. */ + if (DECL_BY_REFERENCE (parm)) + { + 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 +bool parse_integer(const char *first) { + const char *start = first; + inc(first); + return first != start; +} +template bool parse_integer(const char*); + + +struct S { ~S() {} int x; }; +template +bool take_by_invisiref(S s) { + return s.x == 5; +} +template bool take_by_invisiref(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(fmt)) + __builtin_abort(); + + S s{ 5 }; + if (!take_by_invisiref(s)) + __builtin_abort(); +}