From 80bd9eb48190f3554c4de74ccb3d0976831160b1 Mon Sep 17 00:00:00 2001 From: Nathaniel Shead Date: Sun, 5 Jan 2025 23:01:44 +1100 Subject: [PATCH] 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 Reviewed-by: Jason Merrill --- 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 struct S { + template using t = decltype([]{}); +}; + +// 't' does not currently have a mangling scope, but should not ICE +using t = S::t; 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.2