From patchwork Fri Dec 10 19:12:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 48803 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4AA833857C76 for ; Fri, 10 Dec 2021 19:13:17 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4AA833857C76 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1639163597; bh=lER5O/4vmoYhYKZEQTlaJbAr19864mFHeUhkRIktutA=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=TWkv848OSXpEDwedcF/KspHjc8V7Mk/NoWhHaIIvTQUl8MF7fCRnuEH2hjMhqsuem U1ETbc38f6R7qKT4oa/nKP4aKf/T+XbZRhh4VQq5XxF5fpz6D/aDXzWckV5tzojQJ7 h7bOSKoNmio3aVvm634y5iJx7OtZj0xA6gdnaWe0= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 466533858031 for ; Fri, 10 Dec 2021 19:12:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 466533858031 Received: from mail-qv1-f71.google.com (mail-qv1-f71.google.com [209.85.219.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-348-cLlrt8R-Oxmxt8DVZYiUXg-1; Fri, 10 Dec 2021 14:12:44 -0500 X-MC-Unique: cLlrt8R-Oxmxt8DVZYiUXg-1 Received: by mail-qv1-f71.google.com with SMTP id ib7-20020a0562141c8700b0040812bc4425so15481252qvb.16 for ; Fri, 10 Dec 2021 11:12:44 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=lER5O/4vmoYhYKZEQTlaJbAr19864mFHeUhkRIktutA=; b=7olAi1s+sn/FAqisnnP8d5v96F9MKM7IBCE9hGABYxUjQDY/mhbsxkJVSUbgDf5xO6 23E/+KvJzkssUwxuRSxv7DDgTmg8UFQff1yggxDiU//M3694TJJMSIeqdc5LOzXbCNNR kk94Xym5zR5rC1P/tMCiiB5Kk3x3L/Zbk5nm7M/kOMxeykThe8abYSTr/2HaNzvRuPSI uQSUnrPhP3SSyQceIWqYXOVeKBDGO+mnpcuawo8xntgthZ/Q90lysDknBK6wOxrjP4ii 2gEF2n2cp7o8MGECF8yS/BZluyTxEN3Hku1VbVe+GgZjtWimz3ko3tgN1reO9nsz2elc f+lQ== X-Gm-Message-State: AOAM532/u2FSW7JsE+eu1YLC1TaInwHXU+H9IJoac73emVbKdi39yAFu LBBdT3Kxgu3xLPq163B4QC0Y1DGny0PKI4mMBzbGEbmSUnO9go+uVRP+llnbF2tY5E8sUx6ZV9M I6KXCdaloG9sL9Ix77lSySuHaqbR5J3PiDVah1htWen3VB/q10+2+HeV9JmuETDueau4= X-Received: by 2002:a05:620a:2148:: with SMTP id m8mr22111105qkm.435.1639163563535; Fri, 10 Dec 2021 11:12:43 -0800 (PST) X-Google-Smtp-Source: ABdhPJzOXQAknbcjPFQFpEhpimMMpi2jmN7f02nO08xNhy87+wyIKQXHFPkrvzahn4Dn5eF5ILP2Zg== X-Received: by 2002:a05:620a:2148:: with SMTP id m8mr22111035qkm.435.1639163562858; Fri, 10 Dec 2021 11:12:42 -0800 (PST) Received: from localhost.localdomain (ool-457d493a.dyn.optonline.net. [69.125.73.58]) by smtp.gmail.com with ESMTPSA id d15sm2522756qtd.70.2021.12.10.11.12.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Dec 2021 11:12:42 -0800 (PST) To: gcc-patches@gcc.gnu.org Subject: [PATCH] c++: processing_template_decl vs template depth [PR103408] Date: Fri, 10 Dec 2021 14:12:39 -0500 Message-Id: <20211210191239.233081-1-ppalka@redhat.com> X-Mailer: git-send-email 2.34.1.75.gabe6bb3905 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-15.9 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Patrick Palka via Gcc-patches From: Patrick Palka Reply-To: Patrick Palka Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" We use processing_template_decl in two slightly different ways: as a flag to signal that we're dealing with templated trees, and its magnitude is also used as a proxy for the current syntactic template 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 current_template_depth macro. 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). The replacement was mostly mechanical. There were two gotchas: * In synthesize_implicit_template_parm, when introducing a new template parameter list for an abbreviated function template, we need to add a new level of current_template_parms before calling process_template_parm since this function now looks at current_template_depth to determine the level of the new parameter. * In instantiate_class_template_1 when instantiating a template friend, we need to set current_template_parms instead of processing_template_decl so that the friend_depth computation in make_friend_class remains correct. Bootstrpped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk? Also tested on cmcstl2 and rangev3. 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. * decl.c (start_decl): Inspect current_template_depth instead of the magnitude of processing_template_decl. (grokfndecl): Likewise. (grokvardecl): Likewise. (grokdeclarator): Likewise. * friend.c (make_friend_class): Likewise. (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. (add_inherited_template_parms): Likewise. (instantiate_class_template_1): Rename 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-fncast10.C: New test. --- gcc/cp/constraint.cc | 16 ------ gcc/cp/cp-tree.h | 2 + gcc/cp/decl.c | 10 ++-- gcc/cp/friend.c | 4 +- gcc/cp/parser.c | 28 ++++------ gcc/cp/pt.c | 54 +++++++++++--------- gcc/cp/semantics.c | 2 +- gcc/testsuite/g++.dg/concepts/diagnostic18.C | 2 +- gcc/testsuite/g++.dg/cpp23/auto-fncast10.C | 19 +++++++ 9 files changed, 70 insertions(+), 67 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp23/auto-fncast10.C diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 2896efdd7f2..566f4e38fac 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -2016,14 +2016,6 @@ type_deducible_p (tree expr, tree type, tree placeholder, tree args, references are preserved in the result. */ expr = force_paren_expr_uneval (expr); - /* When args is NULL, we're evaluating a non-templated requires expression, - but even those are parsed under processing_template_decl == 1, and so the - placeholder 'auto' inside this return-type-requirement has level 2. In - order to have all parms and arguments match up for satisfaction, we need - to pass an empty level of OUTER_TARGS in this case. */ - if (!args) - args = make_tree_vec (0); - tree deduced_type = do_auto_deduction (type, expr, placeholder, info.complain, adc_requirement, /*outer_targs=*/args); @@ -3064,14 +3056,6 @@ normalize_placeholder_type_constraints (tree t, bool diag) parameters for normalization. */ tree initial_parms = TREE_PURPOSE (ci); - if (!initial_parms && TEMPLATE_TYPE_LEVEL (t) == 2) - /* This is a return-type-requirement of a non-templated requires-expression, - which are parsed under processing_template_decl == 1 and empty - current_template_parms; hence the 'auto' has level 2 and initial_parms - is empty. Fix up initial_parms to be consistent with the value of - processing_template_decl whence the 'auto' was created. */ - initial_parms = build_tree_list (size_int (1), make_tree_vec (0)); - /* The 'auto' itself is used as the first argument in its own constraints, and its level is one greater than its template depth. So in order to capture all used template parameters, we need to add an extra level of diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index b1c3bc5ed1f..9e10a947a43 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1887,6 +1887,8 @@ extern GTY(()) struct saved_scope *scope_chain; stored in the TREE_VALUE. */ #define current_template_parms scope_chain->template_parms +#define current_template_depth \ + (current_template_parms ? TMPL_PARMS_DEPTH (current_template_parms) : 0) #define processing_template_decl scope_chain->x_processing_template_decl #define processing_specialization scope_chain->x_processing_specialization diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 56f80775ca0..7c2048c6acb 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -5567,7 +5567,7 @@ start_decl (const cp_declarator *declarator, if (TYPE_P (context) && COMPLETE_TYPE_P (complete_type (context))) { - bool this_tmpl = (processing_template_decl + bool this_tmpl = (current_template_depth > template_class_depth (context)); if (VAR_P (decl)) { @@ -9878,7 +9878,7 @@ grokfndecl (tree ctype, tree ctx = friendp ? current_class_type : ctype; bool block_local = TREE_CODE (current_scope ()) == FUNCTION_DECL; bool memtmpl = (!block_local - && (processing_template_decl + && (current_template_depth > template_class_depth (ctx))); if (memtmpl) { @@ -10300,7 +10300,7 @@ grokfndecl (tree ctype, if (ctype != NULL_TREE && check) { tree old_decl = check_classfn (ctype, decl, - (processing_template_decl + (current_template_depth > template_class_depth (ctype)) ? current_template_parms : NULL_TREE); @@ -10576,7 +10576,7 @@ grokvardecl (tree type, } } else if (flag_concepts - && processing_template_decl > template_class_depth (scope)) + && current_template_depth > template_class_depth (scope)) { tree reqs = TEMPLATE_PARMS_CONSTRAINTS (current_template_parms); tree ci = build_constraints (reqs, NULL_TREE); @@ -13975,7 +13975,7 @@ grokdeclarator (const cp_declarator *declarator, } /* Set the constraints on the declaration. */ - bool memtmpl = (processing_template_decl + bool memtmpl = (current_template_depth > template_class_depth (current_class_type)); if (memtmpl) { diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c index 4f6288414d9..e970fdce0cc 100644 --- a/gcc/cp/friend.c +++ b/gcc/cp/friend.c @@ -261,7 +261,7 @@ make_friend_class (tree type, tree friend_type, bool complain) The friend is a template friend iff FRIEND_DEPTH is nonzero. */ int class_template_depth = template_class_depth (type); - int friend_depth = processing_template_decl - class_template_depth; + int friend_depth = current_template_depth - class_template_depth; if (! MAYBE_CLASS_TYPE_P (friend_type) && TREE_CODE (friend_type) != TEMPLATE_TEMPLATE_PARM) @@ -517,7 +517,7 @@ do_friend (tree ctype, tree declarator, tree decl, 3. TEMPLATE_MEMBER_P is true (for `W'). */ int class_template_depth = template_class_depth (current_class_type); - int friend_depth = processing_template_decl - class_template_depth; + int friend_depth = current_template_depth - class_template_depth; /* We will figure this out later. */ bool template_member_p = false; diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index de464afdb54..aedfab209ba 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 { diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 9834baf34db..85294f72ba6 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -448,7 +448,7 @@ inline_needs_template_parms (tree decl, bool nsdmi) return false; return (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (most_general_template (decl))) - > (processing_template_decl + DECL_TEMPLATE_SPECIALIZATION (decl))); + > (current_template_depth + DECL_TEMPLATE_SPECIALIZATION (decl))); } /* Subroutine of maybe_begin_member_template_processing. @@ -467,7 +467,7 @@ push_inline_template_parms_recursive (tree parmlist, int levels) ++processing_template_decl; current_template_parms - = tree_cons (size_int (processing_template_decl), + = tree_cons (size_int (current_template_depth + 1), parms, current_template_parms); TEMPLATE_PARMS_FOR_INLINE (current_template_parms) = 1; @@ -523,7 +523,7 @@ maybe_begin_member_template_processing (tree decl) if (inline_needs_template_parms (decl, nsdmi)) { parms = DECL_TEMPLATE_PARMS (most_general_template (decl)); - levels = TMPL_PARMS_DEPTH (parms) - processing_template_decl; + levels = TMPL_PARMS_DEPTH (parms) - current_template_depth; if (DECL_TEMPLATE_SPECIALIZATION (decl)) { @@ -716,7 +716,7 @@ begin_template_parm_list (void) /* Add a dummy parameter level while we process the parameter list. */ current_template_parms - = tree_cons (size_int (processing_template_decl), + = tree_cons (size_int (current_template_depth + 1), make_tree_vec (0), current_template_parms); } @@ -4613,8 +4613,8 @@ process_template_parm (tree list, location_t parm_loc, tree parm, TREE_CONSTANT (decl) = 1; TREE_READONLY (decl) = 1; DECL_INITIAL (parm) = DECL_INITIAL (decl) - = build_template_parm_index (idx, processing_template_decl, - processing_template_decl, + = build_template_parm_index (idx, current_template_depth, + current_template_depth, decl, TREE_TYPE (parm)); TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)) @@ -4655,8 +4655,8 @@ process_template_parm (tree list, location_t parm_loc, tree parm, TYPE_STUB_DECL (t) = decl; parm = decl; TEMPLATE_TYPE_PARM_INDEX (t) - = build_template_parm_index (idx, processing_template_decl, - processing_template_decl, + = build_template_parm_index (idx, current_template_depth, + current_template_depth, decl, TREE_TYPE (parm)); TEMPLATE_TYPE_PARAMETER_PACK (t) = is_parameter_pack; if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM) @@ -4705,7 +4705,7 @@ end_template_parm_list (tree parms) current_template_parms = TREE_CHAIN (current_template_parms); current_template_parms - = tree_cons (size_int (processing_template_decl), + = tree_cons (size_int (current_template_depth + 1), saved_parmlist, current_template_parms); for (unsigned ix = 0; parms; ix++) @@ -6157,7 +6157,7 @@ add_inherited_template_parms (tree fn, tree inherited) = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (inherited)); inner_parms = copy_node (inner_parms); tree parms - = tree_cons (size_int (processing_template_decl + 1), + = tree_cons (size_int (current_template_depth + 1), inner_parms, current_template_parms); tree tmpl = build_template_decl (fn, parms, /*member*/true); tree args = template_parms_to_args (parms); @@ -12165,13 +12165,13 @@ instantiate_class_template_1 (tree type) /* Build new CLASSTYPE_FRIEND_CLASSES. */ tree friend_type = t; - bool adjust_processing_template_decl = false; + bool adjust_template_depth = false; if (TREE_CODE (friend_type) == TEMPLATE_DECL) { /* template friend class C; */ friend_type = tsubst_friend_class (friend_type, args); - adjust_processing_template_decl = true; + adjust_template_depth = true; } else if (TREE_CODE (friend_type) == UNBOUND_CLASS_TEMPLATE) { @@ -12180,7 +12180,7 @@ instantiate_class_template_1 (tree type) tf_warning_or_error, NULL_TREE); if (TREE_CODE (friend_type) == TEMPLATE_DECL) friend_type = TREE_TYPE (friend_type); - adjust_processing_template_decl = true; + adjust_template_depth = true; } else if (TREE_CODE (friend_type) == TYPENAME_TYPE || TREE_CODE (friend_type) == TEMPLATE_TYPE_PARM) @@ -12200,7 +12200,7 @@ instantiate_class_template_1 (tree type) friend_type = tsubst (friend_type, args, tf_warning_or_error, NULL_TREE); if (dependent_type_p (friend_type)) - adjust_processing_template_decl = true; + adjust_template_depth = true; --processing_template_decl; } else if (uses_template_parms (friend_type)) @@ -12218,19 +12218,23 @@ instantiate_class_template_1 (tree type) We don't have to do anything in these cases. */ - if (adjust_processing_template_decl) - /* Trick make_friend_class into realizing that the friend - we're adding is a template, not an ordinary class. It's - important that we use make_friend_class since it will - perform some error-checking and output cross-reference - information. */ - ++processing_template_decl; + if (adjust_template_depth) + { + /* Trick make_friend_class into realizing that the friend + we're adding is a template, not an ordinary class. It's + important that we use make_friend_class since it will + perform some error-checking and output cross-reference + information. */ + gcc_assert (!current_template_parms); + current_template_parms + = build_tree_list (size_int (1), make_tree_vec (0)); + } if (friend_type != error_mark_node) make_friend_class (type, friend_type, /*complain=*/false); - if (adjust_processing_template_decl) - --processing_template_decl; + if (adjust_template_depth) + current_template_parms = TREE_CHAIN (current_template_parms); } else { @@ -28417,7 +28421,7 @@ make_auto_1 (tree name, bool set_canonical) TYPE_NAME (au) = build_decl (input_location, TYPE_DECL, name, au); TYPE_STUB_DECL (au) = TYPE_NAME (au); TEMPLATE_TYPE_PARM_INDEX (au) = build_template_parm_index - (0, processing_template_decl + 1, processing_template_decl + 1, + (0, current_template_depth + 1, current_template_depth + 1, TYPE_NAME (au), NULL_TREE); if (set_canonical) TYPE_CANONICAL (au) = canonical_type_parameter (au); @@ -30070,7 +30074,7 @@ splice_late_return_type (tree type, tree late_return_type) } if (tree auto_node = find_type_usage (type, is_auto)) - if (TEMPLATE_TYPE_LEVEL (auto_node) <= processing_template_decl) + if (TEMPLATE_TYPE_LEVEL (auto_node) <= current_template_depth) { /* In an abbreviated function template we didn't know we were dealing with a function template when we saw the auto return type, so rebuild diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index cdf63c15e21..d8b20ff5b1b 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -3629,7 +3629,7 @@ fixup_template_type (tree type) // the scope we're trying to enter. tree parms = current_template_parms; int depth = template_class_depth (type); - for (int n = processing_template_decl; n > depth && parms; --n) + for (int n = current_template_depth; n > depth && parms; --n) parms = TREE_CHAIN (parms); if (!parms) return type; diff --git a/gcc/testsuite/g++.dg/concepts/diagnostic18.C b/gcc/testsuite/g++.dg/concepts/diagnostic18.C index 79f371b8092..4ac706f8e2d 100644 --- a/gcc/testsuite/g++.dg/concepts/diagnostic18.C +++ b/gcc/testsuite/g++.dg/concepts/diagnostic18.C @@ -4,4 +4,4 @@ void foo(auto&& arg) requires({}); // { dg-error "statement-expressions are not allowed|braced-groups" } template requires ([]{}()); // { dg-error "expected unqualified-id" } -auto f() requires ([]{}()); +auto f() requires ([]{}()); // { dg-error "constraints on a non-templated" } diff --git a/gcc/testsuite/g++.dg/cpp23/auto-fncast10.C b/gcc/testsuite/g++.dg/cpp23/auto-fncast10.C new file mode 100644 index 00000000000..669dda14035 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/auto-fncast10.C @@ -0,0 +1,19 @@ +// PR c++/103408 +// { dg-do compile { target c++23 } } + +static_assert(requires { auto(0); }); +static_assert(requires { auto{0}; }); + +static_assert(requires { auto(auto(0)); }); +static_assert(requires { auto{auto{0}}; }); + +static_assert(requires { auto(auto(auto(0))); }); +static_assert(requires { auto{auto{auto{0}}}; }); + +static_assert(requires { requires auto(true); }); +static_assert(requires { requires auto(auto(true)); }); + +static_assert(!requires { requires auto(false); }); +static_assert(!requires { requires auto(auto(false)); }); + +auto f() requires (auto(false)); // { dg-error "constraints on non-templated" }