Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk? -- >8 --
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> --- 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(-) create mode 100644 gcc/testsuite/g++.dg/modules/lambda-8.h create mode 100644 gcc/testsuite/g++.dg/modules/lambda-8_a.H create mode 100644 gcc/testsuite/g++.dg/modules/lambda-8_b.C diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 1c1eb2e37e2..c89834c1abd 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 00000000000..c4bb20dcf1f --- /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 00000000000..d20958ee140 --- /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 00000000000..7ace4944dd2 --- /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 } -- 2.47.0