#define LAMBDA_EXPR_REGEN_INFO(NODE) \
(((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->regen_info)
+/* Like PACK_EXPANSION_EXTRA_ARGS, for lambda-expressions. */
+#define LAMBDA_EXPR_EXTRA_ARGS(NODE) \
+ (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->extra_args)
+
/* The closure type of the lambda, which is also the type of the
LAMBDA_EXPR. */
#define LAMBDA_EXPR_CLOSURE(NODE) \
tree this_capture;
tree extra_scope;
tree regen_info;
+ tree extra_args;
vec<tree, va_gc> *pending_proxies;
location_t locus;
enum cp_lambda_default_capture_mode_type default_capture_mode : 2;
WT (((lang_tree_node *)t)->lambda_expression.this_capture);
WT (((lang_tree_node *)t)->lambda_expression.extra_scope);
WT (((lang_tree_node *)t)->lambda_expression.regen_info);
+ WT (((lang_tree_node *)t)->lambda_expression.extra_args);
/* pending_proxies is a parse-time thing. */
gcc_assert (!((lang_tree_node *)t)->lambda_expression.pending_proxies);
if (state)
RT (((lang_tree_node *)t)->lambda_expression.this_capture);
RT (((lang_tree_node *)t)->lambda_expression.extra_scope);
RT (((lang_tree_node *)t)->lambda_expression.regen_info);
+ RT (((lang_tree_node *)t)->lambda_expression.extra_args);
/* lambda_expression.pending_proxies is NULL */
((lang_tree_node *)t)->lambda_expression.locus
= state->read_location (*this);
return (PACK_EXPANSION_P (t) /* PACK_EXPANSION_EXTRA_ARGS */
|| TREE_CODE (t) == REQUIRES_EXPR /* REQUIRES_EXPR_EXTRA_ARGS */
|| (TREE_CODE (t) == IF_STMT
- && IF_STMT_CONSTEXPR_P (t))); /* IF_STMT_EXTRA_ARGS */
+ && IF_STMT_CONSTEXPR_P (t)) /* IF_STMT_EXTRA_ARGS */
+ || TREE_CODE (t) == LAMBDA_EXPR); /* LAMBDA_EXPR_EXTRA_ARGS */
}
/* Return *_EXTRA_ARGS of the given supported tree T. */
else if (TREE_CODE (t) == IF_STMT
&& IF_STMT_CONSTEXPR_P (t))
return IF_STMT_EXTRA_ARGS (t);
+ else if (TREE_CODE (t) == LAMBDA_EXPR)
+ return LAMBDA_EXPR_EXTRA_ARGS (t);
gcc_unreachable ();
}
tree oldfn = lambda_function (t);
in_decl = oldfn;
+ args = add_extra_args (LAMBDA_EXPR_EXTRA_ARGS (t), args, complain, in_decl);
+ if (processing_template_decl && !in_template_context)
+ {
+ /* Defer templated substitution into a lambda-expr if we lost the
+ necessary template context. This may happen for a lambda-expr
+ used as a default template argument. */
+ t = copy_node (t);
+ LAMBDA_EXPR_EXTRA_ARGS (t) = NULL_TREE;
+ LAMBDA_EXPR_EXTRA_ARGS (t) = build_extra_args (t, args, complain);
+ return t;
+ }
+
tree r = build_lambda_expr ();
LAMBDA_EXPR_LOCATION (r)
tree type = begin_lambda_type (r);
if (type == error_mark_node)
- return error_mark_node;
+ {
+ gcc_checking_assert (!(complain & tf_error) || seen_error ());
+ return error_mark_node;
+ }
if (LAMBDA_EXPR_EXTRA_SCOPE (t))
record_lambda_scope (r);
--- /dev/null
+// PR c++/114393
+// { dg-do compile { target c++20 } }
+
+template <auto _DescriptorFn> struct c1 {};
+
+template <class _Descriptor, auto t = [] { return _Descriptor(); }>
+inline constexpr auto b_v = t;
+
+template <class _Tag>
+using c1_t = c1<b_v<int>>;
+
+template <class _Data>
+constexpr auto g(_Data __data) {
+ return c1_t<_Data>{};
+}
+
+void f() {
+ auto &&b = g(0);
+}
--- /dev/null
+// PR c++/107457
+// { dg-do compile { target c++20 } }
+
+template<class T>
+using lambda = decltype([]() {});
+
+template<class R, class F = lambda<R>>
+void test() { }
+
+int main() {
+ test<int>();
+}
--- /dev/null
+// PR c++/93595
+// { dg-do compile { target c++20 } }
+
+template<int>
+struct bad {
+ template<class T, auto = []{ return T(); }>
+ static void f(T) { }
+};
+
+int main() {
+ bad<0>::f(0);
+}