]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++/modules: Merge PARM_DECL properties from function definitions [PR121238]
authorNathaniel Shead <nathanieloshead@gmail.com>
Wed, 30 Jul 2025 22:56:09 +0000 (08:56 +1000)
committerNathaniel Shead <nathanieloshead@gmail.com>
Fri, 1 Aug 2025 02:34:00 +0000 (12:34 +1000)
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 <nathanieloshead@gmail.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
Reviewed-by: Patrick Palka <ppalka@redhat.com>
(cherry picked from commit 70136bdc76ae1774162ccbeeedd33aa531950e68)

gcc/cp/module.cc
gcc/testsuite/g++.dg/modules/merge-19.h [new file with mode: 0644]
gcc/testsuite/g++.dg/modules/merge-19_a.H [new file with mode: 0644]
gcc/testsuite/g++.dg/modules/merge-19_b.C [new file with mode: 0644]

index 46d3a3fc14e4449f5b7edbc896cc9be0dae307b2..0aa2992cf5b7c7e58bee3d09af0bbff0d775543b 100644 (file)
@@ -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 (file)
index 0000000..c3faadc
--- /dev/null
@@ -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 (file)
index 0000000..149a447
--- /dev/null
@@ -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 (file)
index 0000000..345e7fe
--- /dev/null
@@ -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();
+}