From 561414cdf8ef0d3c1e2da80b3c8aae56de745b1e Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Tue, 14 Dec 2021 08:15:52 -0500 Subject: c++: processing_template_decl vs template depth [PR103408] We use processing_template_decl in two slightly different ways: as a flag to signal that we're dealing with templated trees, and as a measure of the current syntactic template nesting depth. This overloaded meaning of p_t_d is conceptually confusing and leads to bugs that we end up working around in an ad-hoc fashion. This patch replaces all uses of processing_template_decl that care about its magnitude to instead look at the depth of current_template_parms via a new macro current_template_depth. This allows us to eliminate 3 workarounds in the concepts code: two about non-templated requires-expressions (in constraint.cc) and one about lambdas inside constraints (in cp_parser_requires_clause_expression etc). This also fixes the testcase in PR103408 about auto(x) used inside a non-templated requires-expression. The replacement was mostly mechanical, aside from two issues: * In synthesize_implicit_template_parm, when introducing a new template parameter list for an abbreviated function template, we need to add the new level of current_template_parms sooner, before calling process_template_parm, since this latter function now looks at current_template_depth to determine the level of the new parameter. * In instantiate_class_template_1 after substituting a template friend declaration, we currently increment processing_template_decl around the call to make_friend_class so that the friend_depth computation within this subroutine yields a nonzero value. We could just replace this with an equivalent manipulation of current_template_depth, but this patch instead rewrites the friend_depth calculation within make_friend_class to not depend on p_t_d / c_t_d at all when called from instantiate_class_template_1. PR c++/103408 gcc/cp/ChangeLog: * constraint.cc (type_deducible_p): Remove workaround for non-templated requires-expressions. (normalize_placeholder_type_constraints): Likewise. * cp-tree.h (current_template_depth): Define. (PROCESSING_REAL_TEMPLATE_DECL): Inspect current_template_depth instead of the magnitude of processing_template_decl. * decl.c (start_decl): Likewise. (grokfndecl): Likewise. (grokvardecl): Likewise. (grokdeclarator): Likewise. * friend.c (make_friend_class): Likewise. Calculate friend_depth differently when called at instantiation time instead of parse time. (do_friend): Likewise. * parser.c (cp_parser_requires_clause_expression): Remove workaround for lambdas inside constraints. (cp_parser_constraint_expression): Likewise. (cp_parser_requires_expression): Likewise. (synthesize_implicit_template_parm): Add to current_template_parms before calling process_template_parm. * pt.c (inline_needs_template_parms): Inspect current_template_depth instead of the magnitude of processing_template_decl. (push_inline_template_parms_recursive): Likewise. (maybe_begin_member_template_processing): Likewise. (begin_template_parm_list): Likewise. (process_template_parm): Likewise. (end_template_parm_list): Likewise. (push_template_decl): Likewise. (add_inherited_template_parms): Likewise. (instantiate_class_template_1): Don't adjust processing_template_decl around the call to make_friend_class. adjust_processing_template_decl to adjust_template_depth. Set current_template_parms instead of processing_template_decl when adjust_template_depth. (make_auto_1): Inspect current_template_depth instead of the magnitude of processing_template_decl. (splice_late_return_type): Likewise. * semantics.c (fixup_template_type): Likewise. gcc/testsuite/ChangeLog: * g++.dg/concepts/diagnostic18.C: Expect a "constraints on a non-templated function" error. * g++.dg/cpp23/auto-fncast11.C: New test. --- gcc/cp/parser.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) (limited to 'gcc/cp/parser.c') diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 52225d4..c2564e5 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -29779,14 +29779,9 @@ static tree cp_parser_requires_clause_expression (cp_parser *parser, bool lambda_p) { processing_constraint_expression_sentinel parsing_constraint; - temp_override ovr (processing_template_decl); - if (!processing_template_decl) - /* Adjust processing_template_decl so that we always obtain template - trees here. We don't do the usual ++processing_template_decl - because that would skew the template parameter depth of a lambda - within if we're already inside a template. */ - processing_template_decl = 1; + ++processing_template_decl; cp_expr expr = cp_parser_constraint_logical_or_expression (parser, lambda_p); + --processing_template_decl; if (check_for_bare_parameter_packs (expr)) expr = error_mark_node; return expr; @@ -29805,12 +29800,10 @@ static tree cp_parser_constraint_expression (cp_parser *parser) { processing_constraint_expression_sentinel parsing_constraint; - temp_override ovr (processing_template_decl); - if (!processing_template_decl) - /* As in cp_parser_requires_clause_expression. */ - processing_template_decl = 1; + ++processing_template_decl; cp_expr expr = cp_parser_binary_expression (parser, false, true, PREC_NOT_OPERATOR, NULL); + --processing_template_decl; if (check_for_bare_parameter_packs (expr)) expr = error_mark_node; expr.maybe_add_location_wrapper (); @@ -29924,11 +29917,9 @@ cp_parser_requires_expression (cp_parser *parser) parms = NULL_TREE; /* Parse the requirement body. */ - temp_override ovr (processing_template_decl); - if (!processing_template_decl) - /* As in cp_parser_requires_clause_expression. */ - processing_template_decl = 1; + ++processing_template_decl; reqs = cp_parser_requirement_body (parser); + --processing_template_decl; if (reqs == error_mark_node) return error_mark_node; } @@ -48091,6 +48082,10 @@ synthesize_implicit_template_parm (cp_parser *parser, tree constr) gcc_assert(!proto || TREE_CODE (proto) == TYPE_DECL); synth_tmpl_parm = finish_template_type_parm (class_type_node, synth_id); + if (become_template) + current_template_parms = tree_cons (size_int (current_template_depth + 1), + NULL_TREE, current_template_parms); + /* Attach the constraint to the parm before processing. */ tree node = build_tree_list (NULL_TREE, synth_tmpl_parm); TREE_TYPE (node) = constr; @@ -48130,8 +48125,7 @@ synthesize_implicit_template_parm (cp_parser *parser, tree constr) tree new_parms = make_tree_vec (1); TREE_VEC_ELT (new_parms, 0) = parser->implicit_template_parms; - current_template_parms = tree_cons (size_int (processing_template_decl), - new_parms, current_template_parms); + TREE_VALUE (current_template_parms) = new_parms; } else { -- cgit v1.1