https://gcc.gnu.org/g:abf92b5506f14ce5df48349075aaae0114c5245c
commit r16-8434-gabf92b5506f14ce5df48349075aaae0114c5245c Author: Nathaniel Shead <[email protected]> Date: Sun Mar 15 01:58:41 2026 +1100 c++/modules: Propagate DECL_ARGUMENTS when reading a function def [PR124477] The crash in the given PR occurs because we've streamed the definition of an anticipated builtin, but when processing the nonnull attribute we find that its DECL_ARGUMENTS is null. Back in r14-8196-g3471a61ed0ddef70de8f1bbba85cd1e945fc86fd I removed the setting of DECL_ARGUMENTS as this was causing issues where we were replacing the argument list for existing definitions. This was because the definition we streamed was referencing those same PARM_DECLs, and if they diverged we got different parts of the body with different pointers to the same logical parameter. In most cases we do not need to adjust DECL_ARGUMENTS because fn_parms_fini will substitute in the correct DECL_ARGUMENTS from the existing declaration. But if DECL_ARGUMENTS was not set on the existing declaration at all, as happens with e.g. anticipated builtins, then we do need to set them. PR c++/124477 gcc/cp/ChangeLog: * module.cc (trees_in::read_function_def): Set DECL_ARGUMENTS if installing and otherwise missing. gcc/testsuite/ChangeLog: * g++.dg/modules/builtin-10_a.C: New test. * g++.dg/modules/builtin-10_b.C: New test. Signed-off-by: Nathaniel Shead <[email protected]> Reviewed-by: Jason Merrill <[email protected]> Diff: --- gcc/cp/module.cc | 7 +++++++ gcc/testsuite/g++.dg/modules/builtin-10_a.C | 24 ++++++++++++++++++++++++ gcc/testsuite/g++.dg/modules/builtin-10_b.C | 9 +++++++++ 3 files changed, 40 insertions(+) diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 78f9f3f4d414..6958388e4547 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -13241,6 +13241,13 @@ trees_in::read_function_def (tree decl, tree maybe_template) DECL_INITIAL (decl) = initial; DECL_SAVED_TREE (decl) = saved; + /* Some entities (like anticipated builtins) were declared without + DECL_ARGUMENTS, so update them now. But don't do it if there's + already an argument list, because we've already built the + definition referencing those merged PARM_DECLs. */ + if (!DECL_ARGUMENTS (decl)) + DECL_ARGUMENTS (decl) = DECL_ARGUMENTS (maybe_dup); + if (context) SET_DECL_FRIEND_CONTEXT (decl, context); if (cexpr.decl) diff --git a/gcc/testsuite/g++.dg/modules/builtin-10_a.C b/gcc/testsuite/g++.dg/modules/builtin-10_a.C new file mode 100644 index 000000000000..5c62f88af68a --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/builtin-10_a.C @@ -0,0 +1,24 @@ +// PR c++/124477 +// { dg-additional-options "-fmodules -Wno-global-module -O3" } +// { dg-module-cmi M } + +module; +extern "C" { + typedef __SIZE_TYPE__ size_t; + + extern void *memset (void *__s, int __c, size_t __n) noexcept (true) __attribute__ ((__nonnull__ (1))); + + extern + __inline + __attribute__((__always_inline__)) + __attribute__((__gnu_inline__)) + __attribute__((__artificial__)) + void * + __attribute__((__leaf__)) + memset(void *__dest, int __ch, size_t __len) noexcept(true) { + return __builtin___memset_chk(__dest, __ch, __len, + __builtin_object_size(__dest, 0)); + } +} +export module M; +export using ::memset; diff --git a/gcc/testsuite/g++.dg/modules/builtin-10_b.C b/gcc/testsuite/g++.dg/modules/builtin-10_b.C new file mode 100644 index 000000000000..69303666dd20 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/builtin-10_b.C @@ -0,0 +1,9 @@ +// PR c++/124477 +// { dg-additional-options "-fmodules -O3 -fdump-lang-module-alias" } + +import M; +void foo(void *data) { + memset(data, 0xFF, 4); +} + +// { dg-final { scan-lang-dump {Deduping '::memset'} module } }
