From 2a26351b598242c2fbce95d2a0baacce0084aec6 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 2 Apr 2021 11:05:46 -0400 Subject: c++: lambda pack init-capture within generic lambda We represent the type of a pack init-capture as auto... with packs from the initializer stuck into PACK_EXPANSION_PARAMETER_PACKS so that expanding it produces the right number of elements. But when partially instantiating the auto..., we were changing PACK_EXPANSION_PARAMETER_PACKS to refer to only the auto itself. Fixed thus. gcc/cp/ChangeLog: PR c++/97938 * cp-tree.h (PACK_EXPANSION_AUTO_P): New. * lambda.c (add_capture): Set it. * pt.c (tsubst_pack_expansion): Handle it. gcc/testsuite/ChangeLog: PR c++/97938 * g++.dg/cpp2a/lambda-pack-init6.C: New test. --- gcc/cp/lambda.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'gcc/cp/lambda.c') diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index 421685c..b0fd6ec 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -606,8 +606,11 @@ add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p, parameter pack in this context. We will want as many fields as we have elements in the expansion of the initializer, so use its packs instead. */ - PACK_EXPANSION_PARAMETER_PACKS (type) - = uses_parameter_packs (initializer); + { + PACK_EXPANSION_PARAMETER_PACKS (type) + = uses_parameter_packs (initializer); + PACK_EXPANSION_AUTO_P (type) = true; + } } /* Make member variable. */ -- cgit v1.1 From 123b3e03c911a43054c1f88f5d3110e1d084dd4e Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Thu, 8 Apr 2021 13:07:43 -0400 Subject: c++: Don't substitute into constraints on lambdas [PR99874] We currently substitute through a lambda's constraints whenever we regenerate it via tsubst_lambda_expr. This is the wrong approach because it can lead to hard errors due to constraints being evaluated out of order (as in the testcase concepts-lambda17.C below), and because it doesn't mesh well with the recently added REQUIRES_EXPR_EXTRA_ARGS mechanism for delaying substitution into requires-expressions, which is the cause of this PR. But in order to avoid substituting through a lambda's constraints during regeneration, we need to be able to get at all in-scope template parameters and corresponding template arguments during constraint checking of a lambda's op(). And this information is not easily available when we need it, it seems. To that end, the approach that this patch takes is to add two new fields to LAMBDA_EXPR (and remove one): LAMBDA_EXPR_REGENERATED_FROM (replacing LAMBDA_EXPR_INSTANTIATED), and LAMBDA_EXPR_REGENERATING_TARGS. The former allows us to obtain the complete set of template parameters that are in-scope for a lambda's op(), and the latter gives us all outer template arguments that were used to regenerate the lambda (analogous to the TI_TEMPLATE and TI_ARGS of a TEMPLATE_INFO, respectively). LAMBDA_EXPR_REGENERATING_TARGS is not strictly necessary -- in an earlier prototype, I walked LAMBDA_EXPR_EXTRA_SCOPE to build up this set of outer template arguments on demand, but it seems cleaner to do it this way. (We'd need to walk LAMBDA_EXPR_EXTRA_SCOPE and not DECL/TYPE_CONTEXT because the latter skips over variable template scopes.) This patch also renames the predicate instantiated_lambda_fn_p to regenerated_lambda_fn_p, for sake of consistency with the rest of the patch which uses "regenerated" instead of "instantiated". gcc/cp/ChangeLog: PR c++/99874 * constraint.cc (get_normalized_constraints_from_decl): Handle regenerated lambdas. (satisfy_declaration_constraints): Likewise. Check for dependent args later. * cp-tree.h (LAMBDA_EXPR_INSTANTIATED): Replace with ... (LAMBDA_EXPR_REGENERATED_FROM): ... this. (LAMBDA_EXPR_REGENERATING_TARGS): New. (tree_lambda_expr::regenerated_from): New data member. (tree_lambda_expr::regenerating_targs): New data member. (add_to_template_args): Declare. (regenerated_lambda_fn_p): Likewise. (most_general_lambda): Likewise. * lambda.c (build_lambda_expr): Set LAMBDA_EXPR_REGENERATED_FROM and LAMBDA_EXPR_REGENERATING_TARGS. * pt.c (add_to_template_args): No longer static. (tsubst_function_decl): Unconditionally propagate constraints on the substituted function decl. (instantiated_lambda_fn_p): Rename to ... (regenerated_lambda_fn_p): ... this. Check LAMBDA_EXPR_REGENERATED_FROM instead of LAMBDA_EXPR_INSTANTIATED. (most_general_lambda): Define. (enclosing_instantiation_of): Adjust after renaming instantiated_lambda_fn_p. (tsubst_lambda_expr): Don't set LAMBDA_EXPR_INSTANTIATED. Set LAMBDA_EXPR_REGENERATED_FROM and LAMBDA_EXPR_REGENERATING_TARGS. Don't substitute or set constraints on the regenerated lambda. gcc/testsuite/ChangeLog: PR c++/99874 * g++.dg/cpp2a/concepts-lambda16.C: New test. * g++.dg/cpp2a/concepts-lambda17.C: New test. --- gcc/cp/lambda.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'gcc/cp/lambda.c') diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index b0fd6ec..c0a5ffb 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -41,6 +41,8 @@ build_lambda_expr (void) LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) = CPLD_NONE; LAMBDA_EXPR_CAPTURE_LIST (lambda) = NULL_TREE; LAMBDA_EXPR_THIS_CAPTURE (lambda) = NULL_TREE; + LAMBDA_EXPR_REGENERATED_FROM (lambda) = NULL_TREE; + LAMBDA_EXPR_REGENERATING_TARGS (lambda) = NULL_TREE; LAMBDA_EXPR_PENDING_PROXIES (lambda) = NULL; LAMBDA_EXPR_MUTABLE_P (lambda) = false; return lambda; -- cgit v1.1 From b2576d75ed8900f77849ceacf7fe5f0f3abe734d Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Fri, 9 Apr 2021 17:03:04 -0400 Subject: c++: Use a TEMPLATE_INFO to hold regenerated-lambda info A TEMPLATE_INFO is a natural fit for what LAMBDA_EXPR_REGENERATED_FROM and LAMBDA_EXPR_REGENERATING_TARGS hold, so let's use it instead. gcc/cp/ChangeLog: * cp-tree.h (LAMBDA_EXPR_REGENERATED_FROM) (LAMBDA_EXPR_REGENERATING_TARGS): Replace these with ... (LAMBDA_EXPR_REGEN_INFO): ... this. (tree_lambda_expr::regenerated_from) (tree_lambda_expr::regenerating_targs): Replace these with ... (tree_lambda_expr::regen_info): ... this. * constraint.cc (satisfy_declaration_constraints): Adjust accordingly. * lambda.c (build_lambda_expr): Likewise. * pt.c (regenerated_lambda_fn_p): Likewise. (most_general_lambda): Likewise. (tsubst_lambda_expr): Likewise. --- gcc/cp/lambda.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'gcc/cp/lambda.c') diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index c0a5ffb..16e2b4c 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -41,8 +41,7 @@ build_lambda_expr (void) LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) = CPLD_NONE; LAMBDA_EXPR_CAPTURE_LIST (lambda) = NULL_TREE; LAMBDA_EXPR_THIS_CAPTURE (lambda) = NULL_TREE; - LAMBDA_EXPR_REGENERATED_FROM (lambda) = NULL_TREE; - LAMBDA_EXPR_REGENERATING_TARGS (lambda) = NULL_TREE; + LAMBDA_EXPR_REGEN_INFO (lambda) = NULL_TREE; LAMBDA_EXPR_PENDING_PROXIES (lambda) = NULL; LAMBDA_EXPR_MUTABLE_P (lambda) = false; return lambda; -- cgit v1.1 From fef7c8990da15493110118554adfc9a0b779604c Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Thu, 11 Mar 2021 14:01:52 -0500 Subject: c++: Prune dead functions. I was looking at the LCOV coverage report for the C++ FE and found a bunch of unused functions that I think we can remove. Obviously, I left alone various dump_* and debug_* routines. I haven't removed cp_build_function_call although it is also currently unused. * lambda_return_type: was used in parser.c in GCC 7, unused since r255950, * classtype_has_non_deleted_copy_ctor: appeared in GCC 10, its usage was removed in c++/95350, * contains_wildcard_p: used in GCC 9, unused since r276764, * get_template_head_requirements: seems to never have been used, * check_constrained_friend: seems to never have been used, * subsumes_constraints: unused since r276764, * push_void_library_fn: usage removed in r248328, * get_template_parms_at_level: unused since r157857, * get_pattern_parm: unused since r275387. (Some of the seemingly unused functions, such as set_global_friend, are actually used in libcc1.) gcc/cp/ChangeLog: * class.c (classtype_has_non_deleted_copy_ctor): Remove. * constraint.cc (contains_wildcard_p): Likewise. (get_template_head_requirements): Likewise. (check_constrained_friend): Likewise. (subsumes_constraints): Likewise. * cp-tree.h (classtype_has_non_deleted_copy_ctor): Likewise. (push_void_library_fn): Likewise. (get_pattern_parm): Likewise. (get_template_parms_at_level): Likewise. (lambda_return_type): Likewise. (get_template_head_requirements): Likewise. (check_constrained_friend): Likewise. (subsumes_constraints): Likewise. * decl.c (push_void_library_fn): Likewise. * lambda.c (lambda_return_type): Likewise. * pt.c (get_template_parms_at_level): Likewise. (get_pattern_parm): Likewise. --- gcc/cp/lambda.c | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'gcc/cp/lambda.c') diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index 16e2b4c..4a1e090 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -160,24 +160,6 @@ begin_lambda_type (tree lambda) return type; } -/* Returns the type to use for the return type of the operator() of a - closure class. */ - -tree -lambda_return_type (tree expr) -{ - if (expr == NULL_TREE) - return void_type_node; - if (type_unknown_p (expr) - || BRACE_ENCLOSED_INITIALIZER_P (expr)) - { - cxx_incomplete_type_error (expr, TREE_TYPE (expr)); - return error_mark_node; - } - gcc_checking_assert (!type_dependent_expression_p (expr)); - return cv_unqualified (type_decays_to (unlowered_expr_type (expr))); -} - /* Given a LAMBDA_EXPR or closure type LAMBDA, return the op() of the closure type. */ -- cgit v1.1 From 1a98f830332e5a623278aaeea39c2a88177b2a9a Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 16 Apr 2021 13:52:02 -0400 Subject: c++: preserve BASELINK from lookup [PR91706] In the earlier patch for PR91706 I fixed the BASELINK built by baselink_for_fns, but since we already had one from lookup, we should keep that one around instead of stripping it. The removed hunk in get_class_binding was a wierdly large amount of code to decide whether to pull out BASELINK_FUNCTIONS. gcc/cp/ChangeLog: PR c++/91706 * name-lookup.c (get_class_binding): Keep a BASELINK. (set_inherited_value_binding_p): Adjust. * lambda.c (is_lambda_ignored_entity): Adjust. * pt.c (lookup_template_function): Copy a BASELINK before modifying it. --- gcc/cp/lambda.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'gcc/cp/lambda.c') diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index 4a1e090..2e9d38b 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -1338,9 +1338,9 @@ is_lambda_ignored_entity (tree val) /* None of the lookups that use qualify_lookup want the op() from the lambda; they want the one from the enclosing class. */ - val = OVL_FIRST (val); - if (LAMBDA_FUNCTION_P (val)) - return true; + if (tree fns = maybe_get_fns (val)) + if (LAMBDA_FUNCTION_P (OVL_FIRST (fns))) + return true; return false; } -- cgit v1.1