extern tree maybe_resolve_dummy (tree, bool);
extern tree current_nonlambda_function (void);
extern tree nonlambda_method_basetype (void);
-extern tree current_nonlambda_scope (void);
+extern tree current_nonlambda_scope (bool = false);
extern tree current_lambda_expr (void);
extern bool generic_lambda_fn_p (tree);
extern tree do_dependent_capture (tree, bool = false);
}
}
-/* Like current_scope, but looking through lambdas. */
+/* Like current_scope, but looking through lambdas. If ONLY_SKIP_CLOSURES_P,
+ only look through closure types. */
tree
-current_nonlambda_scope (void)
+current_nonlambda_scope (bool only_skip_closures_p/*=false*/)
{
tree scope = current_scope ();
for (;;)
{
- if (TREE_CODE (scope) == FUNCTION_DECL
+ if (!only_skip_closures_p
+ && TREE_CODE (scope) == FUNCTION_DECL
&& LAMBDA_FUNCTION_P (scope))
{
scope = CP_TYPE_CONTEXT (DECL_CONTEXT (scope));
cp_lexer_consume_token (parser->lexer);
first = false;
- if (!(at_function_scope_p () || parsing_nsdmi ()))
+ tree scope = current_nonlambda_scope (/*only_skip_closures_p=*/true);
+ if (TREE_CODE (scope) != FUNCTION_DECL && !parsing_nsdmi ())
error ("non-local lambda expression cannot have a capture-default");
}
--- /dev/null
+// PR c++/117602
+// { dg-do compile { target c++20 } }
+
+auto x1 = [](decltype([&]{})){}; // { dg-error "non-local lambda" }
+
+auto x2 = [&]() { // { dg-error "non-local lambda" }
+ [&]() { };
+};
+
+auto x3 = []() {
+ [&]() { };
+};
+
+auto x4 = []() {
+ []() { };
+};
+
+auto x5 = [&]() { // { dg-error "non-local lambda" }
+ []() { };
+};
+
+void
+g ()
+{
+ [&](decltype([&](decltype([=](decltype([&](decltype([&]() {})) {})) {})) {})){};
+ [&](decltype([&](decltype([&](decltype([&](decltype([&]() {})) {})) {})) {})){};
+ [=](decltype([=](decltype([=](decltype([=](decltype([&]() {})) {})) {})) {})){};
+
+ [=]() {
+ [&]() { };
+ };
+}