set of template arguments. Augment this with the outer template
arguments that were used to regenerate the lambda. */
gcc_assert (!args || TMPL_ARGS_DEPTH (args) == 1);
- tree lambda = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (t));
- tree outer_args = TI_ARGS (LAMBDA_EXPR_REGEN_INFO (lambda));
+ tree regen_args = lambda_regenerating_args (t);
if (args)
- args = add_to_template_args (outer_args, args);
+ args = add_to_template_args (regen_args, args);
else
- args = outer_args;
+ args = regen_args;
}
/* If any arguments depend on template parameters, we can't
extern tree start_lambda_function (tree fn, tree lambda_expr);
extern void finish_lambda_function (tree body);
extern bool regenerated_lambda_fn_p (tree);
+extern tree lambda_regenerating_args (tree);
extern tree most_general_lambda (tree);
extern tree finish_omp_target (location_t, tree, tree, bool);
extern void finish_omp_target_clauses (location_t, tree, tree *);
return t;
}
+/* Return the set of template arguments used to regenerate the lambda T
+ from its most general lambda. */
+
+tree
+lambda_regenerating_args (tree t)
+{
+ if (LAMBDA_FUNCTION_P (t))
+ t = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (t));
+ gcc_assert (TREE_CODE (t) == LAMBDA_EXPR);
+ if (tree ti = LAMBDA_EXPR_REGEN_INFO (t))
+ return TI_ARGS (ti);
+ else
+ return NULL_TREE;
+}
+
/* We're instantiating a variable from template function TCTX. Return the
corresponding current enclosing scope. We can match them up using
DECL_SOURCE_LOCATION because lambdas only ever have one source location, and
return type;
}
- if ((context == adc_return_type
- || context == adc_variable_type
- || context == adc_decomp_type)
- && current_function_decl
- && DECL_TEMPLATE_INFO (current_function_decl))
- outer_targs = DECL_TI_ARGS (current_function_decl);
+ if (context == adc_return_type
+ || context == adc_variable_type
+ || context == adc_decomp_type)
+ if (tree fn = current_function_decl)
+ if (DECL_TEMPLATE_INFO (fn) || LAMBDA_FUNCTION_P (fn))
+ {
+ outer_targs = DECL_TEMPLATE_INFO (fn)
+ ? DECL_TI_ARGS (fn) : NULL_TREE;
+ if (LAMBDA_FUNCTION_P (fn))
+ {
+ /* As in satisfy_declaration_constraints. */
+ tree regen_args = lambda_regenerating_args (fn);
+ if (outer_targs)
+ outer_targs = add_to_template_args (regen_args, outer_targs);
+ else
+ outer_targs = regen_args;
+ }
+ }
tree full_targs = add_to_template_args (outer_targs, targs);
--- /dev/null
+// PR c++/103706
+// { dg-do compile { target c++20 } }
+
+template<class T, class U> concept C = __is_same(U, int);
+
+template<class T> void f() {
+ []() -> C<T> auto {
+ C<T> auto x = T(); // { dg-error "constraints" }
+ return T(); // { dg-error "constraints" }
+ }();
+}
+
+template void f<int>(); // { dg-bogus "" }
+template void f<char>(); // { dg-message "required from here" }