Skip to content

Commit

Permalink
c++: Support lambdas in static template member initialisers [PR107398]
Browse files Browse the repository at this point in the history
The testcase noted in the PR fails because the context of the lambda is
not in namespace scope, but rather in class scope. This patch removes
the assertion that the context must be a namespace and ensures that
lambdas in class scope still get the correct merge_kind.

	PR c++/107398

gcc/cp/ChangeLog:

	* module.cc (trees_out::get_merge_kind): Handle lambdas in class
	scope.
	(maybe_key_decl): Remove assertion and fix whitespace.

gcc/testsuite/ChangeLog:

	* g++.dg/modules/lambda-6_a.C: New test.
	* g++.dg/modules/lambda-6_b.C: New test.

Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
  • Loading branch information
wreien committed Nov 24, 2023
1 parent a1f8e65 commit cff1fa6
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 15 deletions.
38 changes: 23 additions & 15 deletions gcc/cp/module.cc
Expand Up @@ -10418,13 +10418,16 @@ trees_out::get_merge_kind (tree decl, depset *dep)

case RECORD_TYPE:
case UNION_TYPE:
case NAMESPACE_DECL:
if (DECL_NAME (decl) == as_base_identifier)
mk = MK_as_base;
else if (IDENTIFIER_ANON_P (DECL_NAME (decl)))
mk = MK_field;
break;
{
mk = MK_as_base;
break;
}

case NAMESPACE_DECL:
/* A lambda may have a class as its context, even though it
isn't a member in the traditional sense; see the test
g++.dg/modules/lambda-6_a.C. */
if (DECL_IMPLICIT_TYPEDEF_P (STRIP_TEMPLATE (decl))
&& LAMBDA_TYPE_P (TREE_TYPE (decl)))
if (tree scope
Expand All @@ -10437,6 +10440,13 @@ trees_out::get_merge_kind (tree decl, depset *dep)
break;
}

if (RECORD_OR_UNION_TYPE_P (ctx))
{
if (IDENTIFIER_ANON_P (DECL_NAME (decl)))
mk = MK_field;
break;
}

if (TREE_CODE (decl) == TEMPLATE_DECL
&& DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P (decl))
mk = MK_local_friend;
Expand Down Expand Up @@ -18893,18 +18903,16 @@ maybe_key_decl (tree ctx, tree decl)
if (TREE_CODE (ctx) != VAR_DECL)
return;

gcc_checking_assert (DECL_NAMESPACE_SCOPE_P (ctx));

if (!keyed_table)
if (!keyed_table)
keyed_table = new keyed_map_t (EXPERIMENT (1, 400));

auto &vec = keyed_table->get_or_insert (ctx);
if (!vec.length ())
{
retrofit_lang_decl (ctx);
DECL_MODULE_KEYED_DECLS_P (ctx) = true;
}
vec.safe_push (decl);
auto &vec = keyed_table->get_or_insert (ctx);
if (!vec.length ())
{
retrofit_lang_decl (ctx);
DECL_MODULE_KEYED_DECLS_P (ctx) = true;
}
vec.safe_push (decl);
}

/* Create the flat name string. It is simplest to have it handy. */
Expand Down
16 changes: 16 additions & 0 deletions gcc/testsuite/g++.dg/modules/lambda-6_a.C
@@ -0,0 +1,16 @@
// PR c++/107398
// { dg-additional-options "-fmodules-ts" }
// { dg-module-cmi Lambda6 }

export module Lambda6;

template <typename T>
struct R { static int x; };

template <typename T>
int R<T>::x = []{int i; return 1;}();

export int foo();
int foo() {
return R<int>::x;
}
9 changes: 9 additions & 0 deletions gcc/testsuite/g++.dg/modules/lambda-6_b.C
@@ -0,0 +1,9 @@
// PR c++/107398
// { dg-additional-options "-fmodules-ts" }

import Lambda6;

int main() {
if (foo() != 1)
__builtin_abort();
}

0 comments on commit cff1fa6

Please sign in to comment.