From patchwork Tue Oct 15 04:45:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 1997191 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=THLptDPj; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4XSM5Y3Fb9z1xvK for ; Tue, 15 Oct 2024 15:47:12 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 653363858429 for ; Tue, 15 Oct 2024 04:47:10 +0000 (GMT) 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.129.124]) by sourceware.org (Postfix) with ESMTP id E34DB3858401 for ; Tue, 15 Oct 2024 04:45:49 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org E34DB3858401 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org E34DB3858401 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1728967553; cv=none; b=EcTly7nzhS+FPtan3Bfx2oPUdGUSwt9cexMx0Aje0uV7TojKpSCQ1GvHAetbZtn+c7B6Qm/EAKuGTnofcMy4hOjezT1GnYTkDpHBkHhzpFZqrC3dFEHRY7FHGRKwNejSfSDEl5BvMHu5HhYGcyL7y9UbhpR8aUmJ+YEuP4LGcHk= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1728967553; c=relaxed/simple; bh=LKwATsUNgH2iRt9be0tUNb07R5LmmI/h9/MnPRbr8FU=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=Hv6X02bOHT2m44ELFe0AX2Z8zjLPV7viIvDFNsIhTHrmf3h4wSx+c9x0fV2oLUfxm2RtBYGON2nULastIaJcxOWhDaX3HCIqk/sNERwQ4qnIjKgDnrODeOnJ5vVAwSFfJ+8t33UpWtDnwKbY51pFysb9GW932UNZOaxWZbBprd0= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1728967549; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=q+/bQzhW915UalhM3exbnuZW0istMABu8ICS5IvwkYE=; b=THLptDPjopK6G25GVTt5+RudNmaIznzBnhTaWZGHw1nBl+pnVYwvWMEWLkgI407XcurvJ9 lkeXP2oQHnhBP202D25Bs7QBWdMlLHClJ//kc1TgTq0uJA68KTzv4BmbM79B87wBD1RgL3 d70Wrk+YG2ocXo+gLxTSdyIPofNYBJw= Received: from mail-qv1-f69.google.com (mail-qv1-f69.google.com [209.85.219.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-267-eRMEtrZfMKyTb2o7JuZ-HQ-1; Tue, 15 Oct 2024 00:45:48 -0400 X-MC-Unique: eRMEtrZfMKyTb2o7JuZ-HQ-1 Received: by mail-qv1-f69.google.com with SMTP id 6a1803df08f44-6cbe944435fso10867126d6.1 for ; Mon, 14 Oct 2024 21:45:48 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1728967546; x=1729572346; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=q+/bQzhW915UalhM3exbnuZW0istMABu8ICS5IvwkYE=; b=Ipysfxvo+PsLbzfpkRlIDu2gEhqPK8WydrTYXS+D3FoVblT3KY2QaeNBm7Q/5K46At 8wXL44vnF+NncZe5LYshp8QoiS0197N57qQ20zF621Ckln2u/FKwEniHmOcc8ET3c9Uk Ma5bN3exYolBENjtP6JymDuJB0k5QVijOPWDHTxbKHmCNYTm80ZR+Q4nCUJsICgnGjuy P37V03Q0IQrHU3BvYBJLHaaHxJZidA0uCFeqmTEzpMdGyqi1GrWKKQZ4QiONg/jmE4nJ fnEN/Ppq7hjjpW1NVdaWeTWEbArfkQ8VN5Q1Szk/W72X245N9MHLvduIr0BWEOs9gmGv Jllw== X-Gm-Message-State: AOJu0YyrLX8MW7LvJ1zVmZFV+Wn1jm0JY6ZOwLoaw87ZWVbLk2LiY+v7 9k4ALR3eN6nuWsIWc5F2IaaTBVokJx1+4xTtbeCVBaK1jEe1YOm8UhWX3pYLirWEvCg9GIC7ay6 ARoYlPIh37vPJHiypVv5khaQVKjC57TrmnPl5VqYDkCdCA25YFt0oIT5Ji95T4GLjSpUImaseMC O8+PlJi4A6DgK93k9JWkOYJBLfuB2wYFSK/p6C X-Received: by 2002:a05:620a:46a5:b0:7a9:b52a:a6f2 with SMTP id af79cd13be357-7b11a372a20mr879603285a.8.1728967546255; Mon, 14 Oct 2024 21:45:46 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHhdTTqTiJmLQ0zSnO7UsE6057N3j7qs6jsq8sEGtTTo7lek6nM1GZCTWfMRH1gwF3Hrquxdw== X-Received: by 2002:a05:620a:46a5:b0:7a9:b52a:a6f2 with SMTP id af79cd13be357-7b11a372a20mr879602485a.8.1728967545627; Mon, 14 Oct 2024 21:45:45 -0700 (PDT) Received: from localhost.localdomain (ool-18bb2a2e.dyn.optonline.net. [24.187.42.46]) by smtp.gmail.com with ESMTPSA id af79cd13be357-7b13639518fsm23371985a.87.2024.10.14.21.45.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Oct 2024 21:45:44 -0700 (PDT) From: Patrick Palka To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, Patrick Palka Subject: [PATCH 1/2] c++: some further concepts cleanups Date: Tue, 15 Oct 2024 00:45:35 -0400 Message-ID: <20241015044536.1487876-2-ppalka@redhat.com> X-Mailer: git-send-email 2.47.0.72.gef8ce8f3d4 In-Reply-To: <20241015044536.1487876-1-ppalka@redhat.com> References: <20241015044536.1487876-1-ppalka@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-13.0 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org This patch further cleans up the concepts code following the removal of Concepts TS support: * concept-ids are now the only kind of "concept check", so we can simplify some code accordingly. In particular resolve_concept_check seems like a no-op and can be removed. * In turn, deduce_constrained_parameter doesn't seem to do anything interesting. * In light of the above we might as well inline finish_type_constraints into its only caller. Note that the "prototype parameter" of a concept is just the first template parameter which the caller can easily obtain itself. * placeholder_extract_concept_and_args is only ever called on a concept-id, so it's simpler to inline it into its callers. * There's no such thing as a template-template-parameter wtih a type-constraint, so we can remove such handling from the parser. This means is_constrained_parameter is currently equivalent to declares_constrained_template_template_parameter, so let's prefer to use the latter. We might be able to remove WILDCARD_DECL and CONSTRAINED_PARM_PROTOTYPE now as well, but I left that as future work. gcc/cp/ChangeLog: * constraint.cc (resolve_concept_check): Remove. (deduce_constrained_parameter): Remove. (finish_type_constraints): Inline into its only caller cp_parser_placeholder_type_specifier and remove. (build_concept_check_arguments): Coding style tweaks. (build_standard_check): Inline into its only caller ... (build_concept_check): ... here. (finish_shorthand_constraint): Remove function concept handling. (placeholder_extract_concept_and_args): Inline into its callers and remove. (equivalent_placeholder_constraints): Adjust after placeholder_extract_concept_and_args removal. (iterative_hash_placeholder_constraint): Likewise. * cp-tree.h (type_uses_auto_or_concept): Remove declaration of nonexistent function. (append_type_to_template_for_access_check): Likewise. (finish_type_constraints): Remove declaration. (placeholder_extract_concept_and_args): Remove declaration. (deduce_constrained_parameter): Remove declaration. (resolve_constraint_check): Remove declaration. (valid_requirements_p): Remove declaration of nonexistent function. (finish_concept_name): Likewise. * cxx-pretty-print.cc (pp_cxx_constrained_type_spec): Adjust after placeholder_extract_concept_and_args. * parser.cc (is_constrained_parameter): Inline into declares_constrained_type_template_parameter and remove. (cp_parser_check_constrained_type_parm): Declare static. (finish_constrained_template_template_parm): Remove. (cp_parser_constrained_template_template_parm): Remove. (finish_constrained_parameter): Remove dead code guarded by cp_parser_constrained_template_template_parm. (declares_constrained_type_template_parameter): Adjust after is_constrained_parameter removal. (declares_constrained_template_template_parameter): Remove. (cp_parser_placeholder_type_specifier): Adjust after finish_type_constraints removal. (cp_parser_parameter_declaration): Remove dead code guarded by declares_constrained_template_template_parameter. * pt.cc (make_constrained_placeholder_type): Remove function concept handling. --- gcc/cp/constraint.cc | 181 ++++++------------------------------- gcc/cp/cp-tree.h | 9 -- gcc/cp/cxx-pretty-print.cc | 4 +- gcc/cp/parser.cc | 87 +++--------------- gcc/cp/pt.cc | 5 +- 5 files changed, 42 insertions(+), 244 deletions(-) diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index cf0e5d37571..35be9cc2b41 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -241,88 +241,6 @@ get_concept_check_template (tree t) return TREE_OPERAND (t, 0); } -/*--------------------------------------------------------------------------- - Resolution of qualified concept names ----------------------------------------------------------------------------*/ - -/* This facility is used to resolve constraint checks from requirement - expressions. A constraint check is a call to a function template declared - with the keyword 'concept'. - - The result of resolution is a pair (a TREE_LIST) whose value is the - matched declaration, and whose purpose contains the coerced template - arguments that can be substituted into the call. */ - -/* Returns a pair containing the checked concept and its associated - prototype parameter. The result is a TREE_LIST whose TREE_VALUE - is the concept (non-template) and whose TREE_PURPOSE contains - the converted template arguments, including the deduced prototype - parameter (in position 0). */ - -tree -resolve_concept_check (tree check) -{ - gcc_assert (concept_check_p (check)); - tree tmpl = TREE_OPERAND (check, 0); - tree args = TREE_OPERAND (check, 1); - tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl)); - ++processing_template_decl; - tree result = coerce_template_parms (parms, args, tmpl, tf_none); - --processing_template_decl; - if (result == error_mark_node) - return error_mark_node; - return build_tree_list (result, DECL_TEMPLATE_RESULT (tmpl)); -} - -/* Given a call expression or template-id expression to a concept EXPR - possibly including a wildcard, deduce the concept being checked and - the prototype parameter. Returns true if the constraint and prototype - can be deduced and false otherwise. Note that the CHECK and PROTO - arguments are set to NULL_TREE if this returns false. */ - -bool -deduce_constrained_parameter (tree expr, tree& check, tree& proto) -{ - tree info = resolve_concept_check (expr); - if (info && info != error_mark_node) - { - check = TREE_VALUE (info); - tree arg = TREE_VEC_ELT (TREE_PURPOSE (info), 0); - if (ARGUMENT_PACK_P (arg)) - arg = TREE_VEC_ELT (ARGUMENT_PACK_ARGS (arg), 0); - proto = TREE_TYPE (arg); - return true; - } - - check = proto = NULL_TREE; - return false; -} - -/* Build a constrained placeholder type where SPEC is a type-constraint. - SPEC can be anything were concept_definition_p is true. - - Returns a pair whose FIRST is the concept being checked and whose - SECOND is the prototype parameter. */ - -tree_pair -finish_type_constraints (tree spec, tree args, tsubst_flags_t complain) -{ - gcc_assert (concept_definition_p (spec)); - - /* Build an initial concept check. */ - tree check = build_type_constraint (spec, args, complain); - if (check == error_mark_node) - return std::make_pair (error_mark_node, NULL_TREE); - - /* Extract the concept and prototype parameter from the check. */ - tree con; - tree proto; - if (!deduce_constrained_parameter (check, con, proto)) - return std::make_pair (error_mark_node, NULL_TREE); - - return std::make_pair (con, proto); -} - /*--------------------------------------------------------------------------- Expansion of concept definitions ---------------------------------------------------------------------------*/ @@ -1161,10 +1079,11 @@ get_trailing_function_requirements (tree t) /* Construct a sequence of template arguments by prepending ARG to REST. Either ARG or REST may be null. */ + static tree build_concept_check_arguments (tree arg, tree rest) { - gcc_assert (rest ? TREE_CODE (rest) == TREE_VEC : true); + gcc_assert (!rest || TREE_CODE (rest) == TREE_VEC); tree args; if (arg) { @@ -1178,49 +1097,32 @@ build_concept_check_arguments (tree arg, tree rest) SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (args, def + 1); } else - { - args = rest; - } + args = rest; return args; } -/* Builds an id-expression of the form `C` where C is a standard - concept. */ - -static tree -build_standard_check (tree tmpl, tree args, tsubst_flags_t complain) -{ - gcc_assert (concept_definition_p (tmpl)); - gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL); - if (TREE_DEPRECATED (DECL_TEMPLATE_RESULT (tmpl))) - warn_deprecated_use (DECL_TEMPLATE_RESULT (tmpl), NULL_TREE); - tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl)); - args = coerce_template_parms (parms, args, tmpl, complain); - if (args == error_mark_node) - return error_mark_node; - return build2 (TEMPLATE_ID_EXPR, boolean_type_node, tmpl, args); -} - -/* Construct an expression that checks TARGET using ARGS. */ +/* Construct an expression that checks TMPL using ARGS. */ tree -build_concept_check (tree target, tree args, tsubst_flags_t complain) +build_concept_check (tree tmpl, tree args, tsubst_flags_t complain) { - return build_concept_check (target, NULL_TREE, args, complain); + return build_concept_check (tmpl, NULL_TREE, args, complain); } -/* Construct an expression that checks the concept given by DECL. If - concept_definition_p (DECL) is false, this returns null. */ +/* Construct an expression that checks the concept given by TMPL. */ tree -build_concept_check (tree decl, tree arg, tree rest, tsubst_flags_t complain) +build_concept_check (tree tmpl, tree arg, tree rest, tsubst_flags_t complain) { - tree args = build_concept_check_arguments (arg, rest); - - if (concept_definition_p (decl)) - return build_standard_check (decl, args, complain); + if (TREE_DEPRECATED (DECL_TEMPLATE_RESULT (tmpl))) + warn_deprecated_use (DECL_TEMPLATE_RESULT (tmpl), NULL_TREE); - return error_mark_node; + tree parms = DECL_INNERMOST_TEMPLATE_PARMS (tmpl); + tree args = build_concept_check_arguments (arg, rest); + args = coerce_template_parms (parms, args, tmpl, complain); + if (args == error_mark_node) + return error_mark_node; + return build2 (TEMPLATE_ID_EXPR, boolean_type_node, tmpl, args); } /* Build a template-id that can participate in a concept check. */ @@ -1312,10 +1214,7 @@ finish_shorthand_constraint (tree decl, tree constr) /* Build the concept constraint-expression. */ tree tmpl = DECL_TI_TEMPLATE (con); - tree check = tmpl; - if (TREE_CODE (con) == FUNCTION_DECL) - check = ovl_make (tmpl); - check = build_concept_check (check, arg, args, tf_warning_or_error); + tree check = build_concept_check (tmpl, arg, args, tf_warning_or_error); /* Make the check a fold-expression if needed. Use UNKNOWN_LOCATION so write_template_args can tell the @@ -1345,32 +1244,6 @@ get_shorthand_constraints (tree parms) return result; } -/* Given the concept check T from a constrained-type-specifier, extract - its TMPL and ARGS. FIXME why do we need two different forms of - constrained-type-specifier? */ - -void -placeholder_extract_concept_and_args (tree t, tree &tmpl, tree &args) -{ - if (concept_check_p (t)) - { - tmpl = TREE_OPERAND (t, 0); - args = TREE_OPERAND (t, 1); - return; - } - - if (TREE_CODE (t) == TYPE_DECL) - { - /* A constrained parameter. Build a constraint check - based on the prototype parameter and then extract the - arguments from that. */ - tree proto = CONSTRAINED_PARM_PROTOTYPE (t); - tree check = finish_shorthand_constraint (proto, t); - placeholder_extract_concept_and_args (check, tmpl, args); - return; - } -} - /* Returns true iff the placeholders C1 and C2 are equivalent. C1 and C2 can be either TEMPLATE_TYPE_PARM or template-ids. */ @@ -1393,9 +1266,11 @@ equivalent_placeholder_constraints (tree c1, tree c2) placeholder constraints. */ return false; - tree t1, t2, a1, a2; - placeholder_extract_concept_and_args (c1, t1, a1); - placeholder_extract_concept_and_args (c2, t2, a2); + gcc_assert (concept_check_p (c1) && concept_check_p (c2)); + tree t1 = TREE_OPERAND (c1, 0); + tree a1 = TREE_OPERAND (c1, 1); + tree t2 = TREE_OPERAND (c2, 0); + tree a2 = TREE_OPERAND (c2, 1); if (t1 != t2) return false; @@ -1408,12 +1283,9 @@ equivalent_placeholder_constraints (tree c1, tree c2) /* Skip the first argument so we don't infinitely recurse. Also, they may differ in template parameter index. */ for (int i = 1; i < len1; ++i) - { - tree t1 = TREE_VEC_ELT (a1, i); - tree t2 = TREE_VEC_ELT (a2, i); - if (!template_args_equal (t1, t2)) + if (!template_args_equal (TREE_VEC_ELT (a1, i), + TREE_VEC_ELT (a2, i))) return false; - } return true; } @@ -1422,8 +1294,9 @@ equivalent_placeholder_constraints (tree c1, tree c2) hashval_t iterative_hash_placeholder_constraint (tree c, hashval_t val) { - tree t, a; - placeholder_extract_concept_and_args (c, t, a); + gcc_assert (concept_check_p (c)); + tree t = TREE_OPERAND (c, 0); + tree a = TREE_OPERAND (c, 1); /* Like hash_tmpl_and_args, but skip the first argument. */ val = iterative_hash_object (DECL_UID (t), val); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 94ee550bd9c..1864ab205ae 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -7531,9 +7531,6 @@ extern tree do_auto_deduction (tree, tree, tree, int = LOOKUP_NORMAL, tree = NULL_TREE); extern tree type_uses_auto (tree); -extern tree type_uses_auto_or_concept (tree); -extern void append_type_to_template_for_access_check (tree, tree, tree, - location_t); extern tree convert_generic_types_to_packs (tree, int, int); extern tree splice_late_return_type (tree, tree); extern bool is_auto (const_tree); @@ -8598,15 +8595,9 @@ extern tree build_type_constraint (tree, tree, tsubst_flags_t); extern tree build_concept_check (tree, tree, tsubst_flags_t); extern tree build_concept_check (tree, tree, tree, tsubst_flags_t); -extern tree_pair finish_type_constraints (tree, tree, tsubst_flags_t); extern tree build_constrained_parameter (tree, tree, tree = NULL_TREE); -extern void placeholder_extract_concept_and_args (tree, tree&, tree&); extern bool equivalent_placeholder_constraints (tree, tree); extern hashval_t iterative_hash_placeholder_constraint (tree, hashval_t); -extern bool deduce_constrained_parameter (tree, tree&, tree&); -extern tree resolve_constraint_check (tree); -extern bool valid_requirements_p (tree); -extern tree finish_concept_name (tree); extern tree finish_shorthand_constraint (tree, tree); extern tree finish_requires_expr (location_t, tree, tree); extern tree finish_simple_requirement (location_t, tree); diff --git a/gcc/cp/cxx-pretty-print.cc b/gcc/cp/cxx-pretty-print.cc index 41e6bdfdda5..bf3772d5ac5 100644 --- a/gcc/cp/cxx-pretty-print.cc +++ b/gcc/cp/cxx-pretty-print.cc @@ -2334,8 +2334,8 @@ pp_cxx_constrained_type_spec (cxx_pretty_printer *pp, tree c) pp_cxx_ws_string(pp, ""); return; } - tree t, a; - placeholder_extract_concept_and_args (c, t, a); + tree t = TREE_OPERAND (c, 0); + tree a = TREE_OPERAND (c, 1); pp->id_expression (t); pp_cxx_begin_template_argument_list (pp); pp_cxx_ws_string (pp, ""); diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 9d31a975dcf..856508e3e4f 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -18572,29 +18572,10 @@ get_unqualified_id (cp_declarator *declarator) return NULL_TREE; } -/* Returns true if TYPE would declare a constrained constrained-parameter. */ - -static inline bool -is_constrained_parameter (tree type) -{ - return (type - && TREE_CODE (type) == TYPE_DECL - && CONSTRAINED_PARM_CONCEPT (type) - && DECL_P (CONSTRAINED_PARM_CONCEPT (type))); -} - -/* Returns true if PARM declares a constrained-parameter. */ - -static inline bool -is_constrained_parameter (cp_parameter_declarator *parm) -{ - return is_constrained_parameter (parm->decl_specifiers.type); -} - /* Check that the type parameter is only a declarator-id, and that its type is not cv-qualified. */ -bool +static bool cp_parser_check_constrained_type_parm (cp_parser *parser, cp_parameter_declarator *parm) { @@ -18632,36 +18613,6 @@ cp_parser_constrained_type_template_parm (cp_parser *parser, return error_mark_node; } -static tree -finish_constrained_template_template_parm (tree proto, tree id) -{ - /* FIXME: This should probably be copied, and we may need to adjust - the template parameter depths. */ - tree saved_parms = current_template_parms; - begin_template_parm_list (); - current_template_parms = DECL_TEMPLATE_PARMS (proto); - end_template_parm_list (); - - tree parm = finish_template_template_parm (class_type_node, id); - current_template_parms = saved_parms; - - return parm; -} - -/* Finish parsing/processing a template template parameter by borrowing - the template parameter list from the prototype parameter. */ - -static tree -cp_parser_constrained_template_template_parm (cp_parser *parser, - tree proto, - tree id, - cp_parameter_declarator *parmdecl) -{ - if (!cp_parser_check_constrained_type_parm (parser, parmdecl)) - return error_mark_node; - return finish_constrained_template_template_parm (proto, id); -} - /* Create a new non-type template parameter from the given PARM declarator. */ @@ -18695,9 +18646,6 @@ finish_constrained_parameter (cp_parser *parser, tree parm; if (TREE_CODE (proto) == TYPE_DECL) parm = cp_parser_constrained_type_template_parm (parser, id, parmdecl); - else if (TREE_CODE (proto) == TEMPLATE_DECL) - parm = cp_parser_constrained_template_template_parm (parser, proto, id, - parmdecl); else parm = cp_parser_constrained_non_type_template_parm (is_non_type, parmdecl); if (parm == error_mark_node) @@ -18717,20 +18665,13 @@ finish_constrained_parameter (cp_parser *parser, static bool declares_constrained_type_template_parameter (tree type) { - return (is_constrained_parameter (type) + return (type + && TREE_CODE (type) == TYPE_DECL + && CONSTRAINED_PARM_CONCEPT (type) + && DECL_P (CONSTRAINED_PARM_CONCEPT (type)) && TREE_CODE (TREE_TYPE (type)) == TEMPLATE_TYPE_PARM); } -/* Returns true if the parsed type actually represents the declaration of - a template template-parameter. */ - -static bool -declares_constrained_template_template_parameter (tree type) -{ - return (is_constrained_parameter (type) - && TREE_CODE (TREE_TYPE (type)) == TEMPLATE_TEMPLATE_PARM); -} - /* Parse a default argument for a type template-parameter. Note that diagnostics are handled in cp_parser_template_parameter. */ @@ -18901,7 +18842,8 @@ cp_parser_template_parameter (cp_parser* parser, bool *is_non_type, } /* The parameter may have been constrained type parameter. */ - if (is_constrained_parameter (parameter_declarator)) + tree type = parameter_declarator->decl_specifiers.type; + if (declares_constrained_type_template_parameter (type)) return finish_constrained_parameter (parser, parameter_declarator, is_non_type); @@ -20987,11 +20929,12 @@ cp_parser_placeholder_type_specifier (cp_parser *parser, location_t loc, tsubst_flags_t complain = tentative ? tf_none : tf_warning_or_error; /* Get the concept and prototype parameter for the constraint. */ - tree_pair info = finish_type_constraints (tmpl, args, complain); - tree con = info.first; - tree proto = info.second; - if (con == error_mark_node) + tree check = build_type_constraint (tmpl, args, complain); + if (check == error_mark_node) return error_mark_node; + tree con = STRIP_TEMPLATE (tmpl); + tree parms = DECL_INNERMOST_TEMPLATE_PARMS (tmpl); + tree proto = TREE_VALUE (TREE_VEC_ELT (parms, 0)); /* As per the standard, require auto or decltype(auto). */ cp_token *placeholder = NULL, *close_paren = NULL; @@ -26130,12 +26073,6 @@ cp_parser_parameter_declaration (cp_parser *parser, default_argument = cp_parser_default_type_template_argument (parser); - /* A constrained-type-specifier may declare a - template-template-parameter. */ - else if (declares_constrained_template_template_parameter (type)) - default_argument - = cp_parser_default_template_template_argument (parser); - /* Outside of a class definition, we can just parse the assignment-expression. */ else diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index c0a37a51cba..3d037bd6948 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -29556,11 +29556,8 @@ make_constrained_placeholder_type (tree type, tree con, tree args) { /* Build the constraint. */ tree tmpl = DECL_TI_TEMPLATE (con); - tree expr = tmpl; - if (TREE_CODE (con) == FUNCTION_DECL) - expr = ovl_make (tmpl); ++processing_template_decl; - expr = build_concept_check (expr, type, args, tf_warning_or_error); + tree expr = build_concept_check (tmpl, type, args, tf_warning_or_error); --processing_template_decl; PLACEHOLDER_TYPE_CONSTRAINTS_INFO (type) From patchwork Tue Oct 15 04:46:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 1997192 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=jJuvBKwc; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4XSM6c71hLz1xvK for ; Tue, 15 Oct 2024 15:48:08 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 70AD63857B9F for ; Tue, 15 Oct 2024 04:48:05 +0000 (GMT) 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 ESMTP id 48E983857B91 for ; Tue, 15 Oct 2024 04:46:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 48E983857B91 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 48E983857B91 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1728967610; cv=none; b=SaS4fzdtG/CR94LkbdyyZpttEVGpByRgD9Her1xnnGh1U0dSOnTa4hPG9gc/K/JYNdJWe0+ag1zv4LmgMU89+XX8GcB4bqCXnt+6IwTVQbJ6rnUF/Vh1tq7g7PZ4oY4ayL6Rf4ny7Ten57DPvRXl12AoVW96clExVrd+mCX9R4w= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1728967610; c=relaxed/simple; bh=PNcWgva5TdFK4ps+Vy9/R1aPDra92SQ+pm1XjF5U69I=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=gQwOmm/ZmreJhbmecIoX5QvqRZbTWOyM8v3DOL3ENAzAEoK7hSng8XNZHsU4rT1LJ9olt5Arz8g4qPkc3FRRNGjCrm1oF6Xl59Vsq3WtNB+cP7RKtuc16vsaLK1HvTvNK5rlPR3vD6WnPnOC5pqbaCbhUHEu1IxTXLO6RjzHUBI= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1728967607; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=N9WEJVVEoxN0D76AHsJlNiYIEoB8Vl0KejXvUoWbFbU=; b=jJuvBKwcd4qdFL/MnpCykeyde65qkQHxDGZHx1iRAuYLYe1drwvA3i8FKDv1bXoc6SxKbg jK0XMJzcUeV+YASHju+xeld3sU8/7iWkMdgxeX0eXfV5laBBU0Bpcyeb0GTVXbADti1P5T 4Q8SelivTsuVWzEeSM5wVnPmIl9O7L0= Received: from mail-qt1-f198.google.com (mail-qt1-f198.google.com [209.85.160.198]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-592-CZiuNXBNNjeXShCtZxY-LA-1; Tue, 15 Oct 2024 00:46:45 -0400 X-MC-Unique: CZiuNXBNNjeXShCtZxY-LA-1 Received: by mail-qt1-f198.google.com with SMTP id d75a77b69052e-46049d0c4b0so6695771cf.2 for ; Mon, 14 Oct 2024 21:46:45 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1728967604; x=1729572404; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=N9WEJVVEoxN0D76AHsJlNiYIEoB8Vl0KejXvUoWbFbU=; b=uzbE4aYApAbAx4A1kZDihHwzgB3LGxrQil0XK+tTz2oqQZMKIqfYz2LlXPglts/4rb eZG5KvedecQgk0Crvau0Ire+a1ey4Srm1MC+MeHU4mE/FA8Xp3YsiJfqiDVEMA3I7ymQ 0o2JSYVgvvhoaY55YWfnt8b7gNTKN4yVW6/d/k5AKZ9I7Q1hkg6EWyj6DQalIsjozwrV nCmYPegChmGDjc4U1M42taUMIgWJELRBps++itKa4ir1AF9IRbhpq58jIHr2b0Jggy18 PSqYlFMOr2J6wOKy6yjyd9oMJRwNiSyakNT4piW04bm0IyFwI7XpzHA6ieqiyyaqIuD/ /M5Q== X-Gm-Message-State: AOJu0YzKHvPGpkCEj4Vwo1Hi0QkR1roq9EtHVF0YFED0tjKqxCRGfNIZ oXUDzN08jgrHsps0EUxR5wT6CNlCiCxx8QtTw3+6m3zTQvslIWUDKrdVeeYyJ/F+QzMTwSDObWn TMvLJtf1F1mHnALnVBbB4T+uGnuxgyRBNOWzE8pASUKsu/Jzbgq9V6hIQBEgHzYVK1G+z/qZTk6 /AhMCpRJik0xvPj20yi3QAalSab56g5hQChwzW X-Received: by 2002:ac8:5742:0:b0:458:28f1:c816 with SMTP id d75a77b69052e-4604bbb91f4mr86442321cf.5.1728967603456; Mon, 14 Oct 2024 21:46:43 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEYEv2UfuaSmOK8yz5VHguXLbQA8q6WQS3FJttoe+cnbXvkRizpUFSrA5K0zRa2yuqKLKXN0A== X-Received: by 2002:ac8:5742:0:b0:458:28f1:c816 with SMTP id d75a77b69052e-4604bbb91f4mr86442201cf.5.1728967602739; Mon, 14 Oct 2024 21:46:42 -0700 (PDT) Received: from localhost.localdomain (ool-18bb2a2e.dyn.optonline.net. [24.187.42.46]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-4607b37c047sm2357231cf.65.2024.10.14.21.46.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Oct 2024 21:46:41 -0700 (PDT) From: Patrick Palka To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, Patrick Palka Subject: [PATCH 2/2] c++: constrained auto NTTP vs associated constraints Date: Tue, 15 Oct 2024 00:46:37 -0400 Message-ID: <20241015044637.1487927-1-ppalka@redhat.com> X-Mailer: git-send-email 2.47.0.72.gef8ce8f3d4 In-Reply-To: <20241015044536.1487876-2-ppalka@redhat.com> References: <20241015044536.1487876-2-ppalka@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-13.4 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_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org According to [temp.param]/11, the constraint on an auto NTTP is an associated constraint and so should be checked as part of satisfaction of the overall associated constraints rather than checked individually during coerion/deduction. In order to implement this we mainly need to make handling of constrained auto NTTPs go through finish_constrained_parameter so that TEMPLATE_PARMS_CONSTRAINTS gets set on them. gcc/cp/ChangeLog: * constraint.cc (finish_shorthand_constraint): Add is_non_type parameter for handling constrained (auto) NTTPS. * cp-tree.h (do_auto_deduction): Adjust declaration. (copy_template_args): Declare. (finish_shorthand_constraint): Adjust declaration. * parser.cc (cp_parser_constrained_type_template_parm): Inline into its only caller and remove. (cp_parser_constrained_non_type_template_parm): Likewise. (finish_constrained_parameter): Simplify after the above. (cp_parser_template_parameter): Dispatch to finish_constrained_parameter for a constrained auto NTTP. * pt.cc (process_template_parm): Pass is_non_type to finish_shorthand_constraint. (convert_template_argument): Adjust call to do_auto_deduction. (copy_template_args): Remove static. (unify): Adjust call to do_auto_deduction. (make_constrained_placeholder_type): Return the type not the TYPE_NAME for consistency with make_auto etc. (do_auto_deduction): Remove now unused tmpl parameter. Don't check constraints on an auto NTTP even in a non-template context. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-placeholder12.C: Adjust expected error upon constrained auto NTTP satisfaction failure. * g++.dg/cpp2a/concepts-pr97093.C: Likewise. * g++.dg/cpp2a/concepts-template-parm2.C: Likewise. * g++.dg/cpp2a/concepts-template-parm6.C: Likewise. --- gcc/cp/constraint.cc | 32 +++++++++-- gcc/cp/cp-tree.h | 6 +-- gcc/cp/parser.cc | 54 +++++++------------ gcc/cp/pt.cc | 35 +++++------- .../g++.dg/cpp2a/concepts-placeholder12.C | 4 +- gcc/testsuite/g++.dg/cpp2a/concepts-pr97093.C | 2 +- .../g++.dg/cpp2a/concepts-template-parm2.C | 2 +- .../g++.dg/cpp2a/concepts-template-parm6.C | 2 +- 8 files changed, 66 insertions(+), 71 deletions(-) diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 35be9cc2b41..9394bea8835 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -1189,7 +1189,7 @@ build_constrained_parameter (tree cnc, tree proto, tree args) done only after the requires clause has been parsed (or not). */ tree -finish_shorthand_constraint (tree decl, tree constr) +finish_shorthand_constraint (tree decl, tree constr, bool is_non_type) { /* No requirements means no constraints. */ if (!constr) @@ -1198,9 +1198,22 @@ finish_shorthand_constraint (tree decl, tree constr) if (error_operand_p (constr)) return NULL_TREE; - tree proto = CONSTRAINED_PARM_PROTOTYPE (constr); - tree con = CONSTRAINED_PARM_CONCEPT (constr); - tree args = CONSTRAINED_PARM_EXTRA_ARGS (constr); + tree proto, con, args; + if (is_non_type) + { + tree id = PLACEHOLDER_TYPE_CONSTRAINTS (constr); + tree tmpl = TREE_OPERAND (id, 0); + tree parms = DECL_INNERMOST_TEMPLATE_PARMS (tmpl); + proto = TREE_VALUE (TREE_VEC_ELT (parms, 0)); + con = DECL_TEMPLATE_RESULT (tmpl); + args = TREE_OPERAND (id, 1); + } + else + { + proto = CONSTRAINED_PARM_PROTOTYPE (constr); + con = CONSTRAINED_PARM_CONCEPT (constr); + args = CONSTRAINED_PARM_EXTRA_ARGS (constr); + } bool variadic_concept_p = template_parameter_pack_p (proto); bool declared_pack_p = template_parameter_pack_p (decl); @@ -1214,7 +1227,16 @@ finish_shorthand_constraint (tree decl, tree constr) /* Build the concept constraint-expression. */ tree tmpl = DECL_TI_TEMPLATE (con); - tree check = build_concept_check (tmpl, arg, args, tf_warning_or_error); + tree check; + if (is_non_type) + { + arg = finish_decltype_type (arg, /*id_expr=*/true, tf_warning_or_error); + args = copy_template_args (args); + TREE_VEC_ELT (args, 0) = arg; + check = build_concept_check (tmpl, args, tf_warning_or_error); + } + else + check = build_concept_check (tmpl, arg, args, tf_warning_or_error); /* Make the check a fold-expression if needed. Use UNKNOWN_LOCATION so write_template_args can tell the diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 1864ab205ae..1e202e17658 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -7528,8 +7528,7 @@ extern tree do_auto_deduction (tree, tree, tree, auto_deduction_context = adc_unspecified, tree = NULL_TREE, - int = LOOKUP_NORMAL, - tree = NULL_TREE); + int = LOOKUP_NORMAL); extern tree type_uses_auto (tree); extern tree convert_generic_types_to_packs (tree, int, int); extern tree splice_late_return_type (tree, tree); @@ -7587,6 +7586,7 @@ extern bool is_specialization_of_friend (tree, tree); extern bool comp_template_args (tree, tree, tree * = NULL, tree * = NULL); extern int template_args_equal (tree, tree); +extern tree copy_template_args (tree); extern tree maybe_process_partial_specialization (tree); extern tree most_specialized_instantiation (tree); extern tree most_specialized_partial_spec (tree, tsubst_flags_t, bool = false); @@ -8598,7 +8598,7 @@ extern tree build_concept_check (tree, tree, tree, tsubst_flags_ extern tree build_constrained_parameter (tree, tree, tree = NULL_TREE); extern bool equivalent_placeholder_constraints (tree, tree); extern hashval_t iterative_hash_placeholder_constraint (tree, hashval_t); -extern tree finish_shorthand_constraint (tree, tree); +extern tree finish_shorthand_constraint (tree, tree, bool); extern tree finish_requires_expr (location_t, tree, tree); extern tree finish_simple_requirement (location_t, tree); extern tree finish_type_requirement (location_t, tree); diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 856508e3e4f..9a12e35a759 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -18599,34 +18599,6 @@ cp_parser_check_constrained_type_parm (cp_parser *parser, return true; } -/* Finish parsing/processing a template type parameter and checking - various restrictions. */ - -static inline tree -cp_parser_constrained_type_template_parm (cp_parser *parser, - tree id, - cp_parameter_declarator* parmdecl) -{ - if (cp_parser_check_constrained_type_parm (parser, parmdecl)) - return finish_template_type_parm (class_type_node, id); - else - return error_mark_node; -} - -/* Create a new non-type template parameter from the given PARM - declarator. */ - -static tree -cp_parser_constrained_non_type_template_parm (bool *is_non_type, - cp_parameter_declarator *parm) -{ - *is_non_type = true; - cp_declarator *decl = parm->declarator; - cp_decl_specifier_seq *specs = &parm->decl_specifiers; - specs->type = TREE_TYPE (DECL_INITIAL (specs->type)); - return grokdeclarator (decl, specs, TPARM, 0, NULL); -} - /* Build a constrained template parameter based on the PARMDECL declarator. The type of PARMDECL is the constrained type, which refers to the prototype template parameter that ultimately @@ -18637,24 +18609,33 @@ finish_constrained_parameter (cp_parser *parser, cp_parameter_declarator *parmdecl, bool *is_non_type) { - tree decl = parmdecl->decl_specifiers.type; + tree type = parmdecl->decl_specifiers.type; tree id = get_unqualified_id (parmdecl->declarator); tree def = parmdecl->default_argument; - tree proto = DECL_INITIAL (decl); /* Build the parameter. Return an error if the declarator was invalid. */ tree parm; - if (TREE_CODE (proto) == TYPE_DECL) - parm = cp_parser_constrained_type_template_parm (parser, id, parmdecl); + if (is_auto (type)) + { + *is_non_type = true; + parm = grokdeclarator (parmdecl->declarator, + &parmdecl->decl_specifiers, + TPARM, /*initialized=*/0, /*attrlist=*/NULL); + } else - parm = cp_parser_constrained_non_type_template_parm (is_non_type, parmdecl); + { + if (cp_parser_check_constrained_type_parm (parser, parmdecl)) + parm = finish_template_type_parm (class_type_node, id); + else + parm = error_mark_node; + } if (parm == error_mark_node) return error_mark_node; /* Finish the parameter decl and create a node attaching the default argument and constraint. */ parm = build_tree_list (def, parm); - TEMPLATE_PARM_CONSTRAINTS (parm) = decl; + TEMPLATE_PARM_CONSTRAINTS (parm) = type; return parm; } @@ -18841,9 +18822,10 @@ cp_parser_template_parameter (cp_parser* parser, bool *is_non_type, cp_lexer_consume_token (parser->lexer); } - /* The parameter may have been constrained type parameter. */ + /* The parameter may be a constrained type or non-type parameter. */ tree type = parameter_declarator->decl_specifiers.type; - if (declares_constrained_type_template_parameter (type)) + if (declares_constrained_type_template_parameter (type) + || (type && is_constrained_auto (type))) return finish_constrained_parameter (parser, parameter_declarator, is_non_type); diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 3d037bd6948..af784a41265 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -183,7 +183,6 @@ static int template_decl_level (tree); static int check_cv_quals_for_unify (int, tree, tree); static int unify_pack_expansion (tree, tree, tree, tree, unification_kind_t, bool, bool); -static tree copy_template_args (tree); static tree tsubst_template_parms (tree, tree, tsubst_flags_t); static void tsubst_each_template_parm_constraints (tree, tree, tsubst_flags_t); static tree tsubst_arg_types (tree, tree, tree, tsubst_flags_t, tree); @@ -4736,7 +4735,7 @@ process_template_parm (tree list, location_t parm_loc, tree parm, /* Build requirements for the type/template parameter. This must be done after SET_DECL_TEMPLATE_PARM_P or process_template_parm could fail. */ - tree reqs = finish_shorthand_constraint (parm, constr); + tree reqs = finish_shorthand_constraint (parm, constr, is_non_type); decl = pushdecl (decl); if (!is_non_type) @@ -8831,7 +8830,7 @@ convert_template_argument (tree parm, else if (tree a = type_uses_auto (t)) { t = do_auto_deduction (t, arg, a, complain, adc_unify, args, - LOOKUP_IMPLICIT, /*tmpl=*/in_decl); + LOOKUP_IMPLICIT); if (t == error_mark_node) return error_mark_node; } @@ -13967,7 +13966,7 @@ make_argument_pack (tree vec) /* Return an exact copy of template args T that can be modified independently. */ -static tree +tree copy_template_args (tree t) { if (t == error_mark_node) @@ -25044,8 +25043,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, { tparm = do_auto_deduction (tparm, arg, a, complain, adc_unify, targs, - LOOKUP_NORMAL, - TPARMS_PRIMARY_TEMPLATE (tparms)); + LOOKUP_NORMAL); if (tparm == error_mark_node) return 1; } @@ -29566,8 +29564,7 @@ make_constrained_placeholder_type (tree type, tree con, tree args) /* Our canonical type depends on the constraint. */ TYPE_CANONICAL (type) = canonical_type_parameter (type); - /* Attach the constraint to the type declaration. */ - return TYPE_NAME (type); + return type; } /* Make a "constrained auto" type-specifier. */ @@ -31187,10 +31184,7 @@ unparenthesized_id_or_class_member_access_p (tree init) adc_requirement contexts to communicate the necessary template arguments to satisfaction. OUTER_TARGS is ignored in other contexts. - Additionally for adc_unify contexts TMPL is the template for which TYPE - is a template parameter type. - - For partial-concept-ids, extra args from OUTER_TARGS, TMPL and the current + For partial-concept-ids, extra args from OUTER_TARGS and the current scope may be appended to the list of deduced template arguments prior to determining constraint satisfaction as appropriate. */ @@ -31199,8 +31193,7 @@ do_auto_deduction (tree type, tree init, tree auto_node, tsubst_flags_t complain /* = tf_warning_or_error */, auto_deduction_context context /* = adc_unspecified */, tree outer_targs /* = NULL_TREE */, - int flags /* = LOOKUP_NORMAL */, - tree tmpl /* = NULL_TREE */) + int flags /* = LOOKUP_NORMAL */) { if (type == error_mark_node || init == error_mark_node) return error_mark_node; @@ -31348,8 +31341,10 @@ do_auto_deduction (tree type, tree init, tree auto_node, } /* Check any placeholder constraints against the deduced type. */ - if (processing_template_decl && context == adc_unify) - /* Constraints will be checked after deduction. */; + if (context == adc_unify) + /* These constraints correspond to a constrained auto NTTP and are part + of the template's associated constraints which will get checked as a + whole after coercion/deduction. */; else if (tree constr = NON_ERROR (PLACEHOLDER_TYPE_CONSTRAINTS (auto_node))) { if (processing_template_decl) @@ -31383,10 +31378,7 @@ do_auto_deduction (tree type, tree init, tree auto_node, } } - tree full_targs = outer_targs; - if (context == adc_unify && tmpl) - full_targs = add_outermost_template_args (tmpl, full_targs); - full_targs = add_to_template_args (full_targs, targs); + tree full_targs = add_to_template_args (outer_targs, targs); /* HACK: Compensate for callers not always communicating all levels of outer template arguments by filling in the outermost missing levels @@ -31411,8 +31403,7 @@ do_auto_deduction (tree type, tree init, tree auto_node, auto_diagnostic_group d; switch (context) { - case adc_unspecified: - case adc_unify: + default: error_at (loc, "placeholder constraints not satisfied"); break; case adc_variable_type: diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder12.C b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder12.C index 22f0ac5e26a..edca8f7199b 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder12.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder12.C @@ -22,8 +22,8 @@ int main() { A::g(X<0>{}); // { dg-error "no match|constraints" } bool v1 = A::value<0>; - bool v2 = A::value<0>; // { dg-error "constraints" } + bool v2 = A::value<0>; // { dg-error "invalid variable template" } A::D<0> d1; - A::D<0> d2; // { dg-error "constraints" } + A::D<0> d2; // { dg-error "constraint failure" } } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr97093.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr97093.C index d662552614e..355f195ac0a 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr97093.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr97093.C @@ -29,4 +29,4 @@ struct pc }; constexpr auto cc = pc {}; -constexpr auto mmcc = m {}; // { dg-error "not satisfied" } +constexpr auto mmcc = m {}; // { dg-error "constraint failure" } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-template-parm2.C b/gcc/testsuite/g++.dg/cpp2a/concepts-template-parm2.C index 3bb2f576a87..a9b15dabc0c 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-template-parm2.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-template-parm2.C @@ -12,4 +12,4 @@ template struct S1 { }; template struct S2 { }; S1<> s1; // { dg-error "constraint failure" } -S2<> s2; // { dg-error "placeholder constraints not satisfied" } +S2<> s2; // { dg-error "constraint failure" } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-template-parm6.C b/gcc/testsuite/g++.dg/cpp2a/concepts-template-parm6.C index c7d9964f738..04c2e1c70ba 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-template-parm6.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-template-parm6.C @@ -40,5 +40,5 @@ template struct S3 { }; // requires (C && ...) S3 x0; // { dg-error "template constraint failure" } template struct S4 { }; // requires (C && ...) with each X deduced -S4<0, 1, 2, 'a'> x1; // { dg-error "placeholder constraints not satisfied" } +S4<0, 1, 2, 'a'> x1; // { dg-error "template constraint failure" }