Skip to content

Commit 80bd9eb

Browse files
committed
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 <nathanieloshead@gmail.com> Reviewed-by: Jason Merrill <jason@redhat.com>
1 parent 4c01f40 commit 80bd9eb

File tree

4 files changed

+37
-12
lines changed

4 files changed

+37
-12
lines changed

gcc/cp/module.cc

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11014,18 +11014,23 @@ trees_out::get_merge_kind (tree decl, depset *dep)
1101411014
g++.dg/modules/lambda-6_a.C. */
1101511015
if (DECL_IMPLICIT_TYPEDEF_P (STRIP_TEMPLATE (decl))
1101611016
&& LAMBDA_TYPE_P (TREE_TYPE (decl)))
11017-
if (tree scope = LAMBDA_TYPE_EXTRA_SCOPE (TREE_TYPE (decl)))
11018-
{
11019-
/* Lambdas attached to fields are keyed to its class. */
11020-
if (TREE_CODE (scope) == FIELD_DECL)
11021-
scope = TYPE_NAME (DECL_CONTEXT (scope));
11022-
if (DECL_LANG_SPECIFIC (scope)
11023-
&& DECL_MODULE_KEYED_DECLS_P (scope))
11024-
{
11025-
mk = MK_keyed;
11026-
break;
11027-
}
11028-
}
11017+
{
11018+
if (tree scope = LAMBDA_TYPE_EXTRA_SCOPE (TREE_TYPE (decl)))
11019+
{
11020+
/* Lambdas attached to fields are keyed to its class. */
11021+
if (TREE_CODE (scope) == FIELD_DECL)
11022+
scope = TYPE_NAME (DECL_CONTEXT (scope));
11023+
if (DECL_LANG_SPECIFIC (scope)
11024+
&& DECL_MODULE_KEYED_DECLS_P (scope))
11025+
{
11026+
mk = MK_keyed;
11027+
break;
11028+
}
11029+
}
11030+
/* Lambdas not attached to any mangling scope are TU-local. */
11031+
mk = MK_unique;
11032+
break;
11033+
}
1102911034

1103011035
if (TREE_CODE (decl) == TEMPLATE_DECL
1103111036
&& DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P (decl))
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// PR c++/116568
2+
3+
template <typename> struct S {
4+
template <typename> using t = decltype([]{});
5+
};
6+
7+
// 't' does not currently have a mangling scope, but should not ICE
8+
using t = S<int>::t<int>;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// PR c++/116568
2+
// { dg-additional-options "-fmodules-ts -std=c++20" }
3+
// { dg-module-cmi {} }
4+
5+
#include "lambda-8.h"
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// PR c++/116568
2+
// { dg-additional-options "-fmodules-ts -fno-module-lazy -std=c++20" }
3+
4+
#include "lambda-8.h"
5+
import "lambda-8_a.H";
6+
7+
// { dg-error "conflicting global module declaration" "" { target *-*-* } 0 }

0 commit comments

Comments
 (0)