https://gcc.gnu.org/g:80bd9eb48190f3554c4de74ccb3d0976831160b1
commit r15-7204-g80bd9eb48190f3554c4de74ccb3d0976831160b1 Author: Nathaniel Shead <nathanielosh...@gmail.com> Date: Sun Jan 5 23:01:44 2025 +1100 c++/modules: Treat unattached lambdas as TU-local [PR116568] This fixes ICEs where unattached lambdas at class scope (for instance, in member template instantiations) are streamed. This is only possible in header units, as in named modules attempting to stream such lambdas will be an error. PR c++/116568 gcc/cp/ChangeLog: * module.cc (trees_out::get_merge_kind): Treat all lambdas without a mangling scope as un-mergeable. gcc/testsuite/ChangeLog: * g++.dg/modules/lambda-8.h: New test. * g++.dg/modules/lambda-8_a.H: New test. * g++.dg/modules/lambda-8_b.C: New test. Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com> Reviewed-by: Jason Merrill <ja...@redhat.com> Diff: --- gcc/cp/module.cc | 29 +++++++++++++++++------------ gcc/testsuite/g++.dg/modules/lambda-8.h | 8 ++++++++ gcc/testsuite/g++.dg/modules/lambda-8_a.H | 5 +++++ gcc/testsuite/g++.dg/modules/lambda-8_b.C | 7 +++++++ 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 1c1eb2e37e2d..c89834c1abdf 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -11014,18 +11014,23 @@ trees_out::get_merge_kind (tree decl, depset *dep) g++.dg/modules/lambda-6_a.C. */ if (DECL_IMPLICIT_TYPEDEF_P (STRIP_TEMPLATE (decl)) && LAMBDA_TYPE_P (TREE_TYPE (decl))) - if (tree scope = LAMBDA_TYPE_EXTRA_SCOPE (TREE_TYPE (decl))) - { - /* Lambdas attached to fields are keyed to its class. */ - if (TREE_CODE (scope) == FIELD_DECL) - scope = TYPE_NAME (DECL_CONTEXT (scope)); - if (DECL_LANG_SPECIFIC (scope) - && DECL_MODULE_KEYED_DECLS_P (scope)) - { - mk = MK_keyed; - break; - } - } + { + if (tree scope = LAMBDA_TYPE_EXTRA_SCOPE (TREE_TYPE (decl))) + { + /* Lambdas attached to fields are keyed to its class. */ + if (TREE_CODE (scope) == FIELD_DECL) + scope = TYPE_NAME (DECL_CONTEXT (scope)); + if (DECL_LANG_SPECIFIC (scope) + && DECL_MODULE_KEYED_DECLS_P (scope)) + { + mk = MK_keyed; + break; + } + } + /* Lambdas not attached to any mangling scope are TU-local. */ + mk = MK_unique; + break; + } if (TREE_CODE (decl) == TEMPLATE_DECL && DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P (decl)) diff --git a/gcc/testsuite/g++.dg/modules/lambda-8.h b/gcc/testsuite/g++.dg/modules/lambda-8.h new file mode 100644 index 000000000000..c4bb20dcf1f9 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/lambda-8.h @@ -0,0 +1,8 @@ +// PR c++/116568 + +template <typename> struct S { + template <typename> using t = decltype([]{}); +}; + +// 't' does not currently have a mangling scope, but should not ICE +using t = S<int>::t<int>; diff --git a/gcc/testsuite/g++.dg/modules/lambda-8_a.H b/gcc/testsuite/g++.dg/modules/lambda-8_a.H new file mode 100644 index 000000000000..d20958ee140f --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/lambda-8_a.H @@ -0,0 +1,5 @@ +// PR c++/116568 +// { dg-additional-options "-fmodules-ts -std=c++20" } +// { dg-module-cmi {} } + +#include "lambda-8.h" diff --git a/gcc/testsuite/g++.dg/modules/lambda-8_b.C b/gcc/testsuite/g++.dg/modules/lambda-8_b.C new file mode 100644 index 000000000000..7ace4944dd2d --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/lambda-8_b.C @@ -0,0 +1,7 @@ +// PR c++/116568 +// { dg-additional-options "-fmodules-ts -fno-module-lazy -std=c++20" } + +#include "lambda-8.h" +import "lambda-8_a.H"; + +// { dg-error "conflicting global module declaration" "" { target *-*-* } 0 }