From patchwork Fri Feb 2 19:41:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 85245 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 E2CEA385802D for ; Fri, 2 Feb 2024 19:41:50 +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 ESMTPS id 7B1D1385841F for ; Fri, 2 Feb 2024 19:41:09 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 7B1D1385841F 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 7B1D1385841F 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=1706902872; cv=none; b=jivXgEKlS4x29cjiCD6LCmkFj3bES2mK37fS5q6G25Sn7tHXQzkPKEls0SozArjdCtWefNg4BNLLca9a9b/9CMmCjKX/Z3tkEBlyfuoYa6vYozt3VXKBiziFlhKs4Ny272qTSv3TxOeJb1lVRd1hYjxz4TTECtK1CL34kpmu4Jk= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1706902872; c=relaxed/simple; bh=7V/px2zx0hp3IHg+2V+Q2A3jHWMydegA16ukMLPbp8Q=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=BuOUPhbHQcX1LyCJO207K8YujO1ZU9RQ0xzDALA5lWHLObTOeraofdpER9VI4raycBA9zRLpGQuDDKiJmv5TrGiHBFJY5WxtRWb6PFFJLwnJMfjOKiwsr8cTMzS2lg5UpNT/3xwdd3DxzxRX/4BnUu/+OvW666Cx6It2bHlzgDE= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1706902869; 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; bh=qcsYBQ40QA2cutlJ7ySUmqEFXQxOlCEgkGoGP8oiE9U=; b=RToLxrpQaLie8vn1RdXBMxMFLPIxto3SYV/yMHvA4qu8I1NbiLgZ1iRrfcGt60CzN3PprP tC4PF6NWldYnYNwUw/o3eccrE94CIQg+LoUpcC3kQxHZxvslFc9umUP2hpMRuc7926K8Xr 7M0tKdIEYuRzja5JrpN/P9RZhXFx074= Received: from mail-qv1-f72.google.com (mail-qv1-f72.google.com [209.85.219.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-630-d9KLUTF_Mu6gdkR7hccc3w-1; Fri, 02 Feb 2024 14:41:08 -0500 X-MC-Unique: d9KLUTF_Mu6gdkR7hccc3w-1 Received: by mail-qv1-f72.google.com with SMTP id 6a1803df08f44-68c43a4cc11so38531566d6.1 for ; Fri, 02 Feb 2024 11:41:07 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706902866; x=1707507666; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=qcsYBQ40QA2cutlJ7ySUmqEFXQxOlCEgkGoGP8oiE9U=; b=GazegTYZWCM+2UPbR5a8tZfGVrOx3EJi96iUWCavzGl6Y08Kf7FgXBYzSAyW3c/390 FVCeMuPcb+3iJAC1dAjOPB95iLymJ0REwIuplRd1bXpz4loP0tPloFmti/6XQ2bH5K+Z 8zcTr24jCth+98kCee12wmewFI85XFz4qFRN3ux64aPTikFNhrIi/dDN2hzW98WjAi7V oi3rwf4uRY0BbWkUz8axBKw9wMsCCV4r7AEF5CMEn2iiZ9ItA15X6SF5Vmvq7pkOm3Iv R/Jic7Z6J0jGv1bmKv67+yGQ2X/tLG24vy3mGFtZVjYIDAtsTnBmLJ+3z1WzxLrRDG5D bSCg== X-Gm-Message-State: AOJu0Yyz9FyRZelOQwgYNsfirBHC7kEMte9mMHVP7v6rFvKMgBgXHpy3 gCyyrCwSm7NsSMZV2bH8XPfxrBf5CDJ4EwEGk3jtOYBza6FW2jJYJaEiNxIujtnJ1Acu3MyYCMK FvyPVch0hIZqYYb+7Jxj4fH8LDrTNvUNl5nJkRFAwWORj7ez4JEYYIy/xLZYUaRN7JRQpWXV0t0 9H/KZAVcGotnI3uXNUG4SBWtZij3cy+dd+sUKK X-Received: by 2002:a0c:cc0c:0:b0:68c:8aaf:3536 with SMTP id r12-20020a0ccc0c000000b0068c8aaf3536mr1548254qvk.6.1706902866385; Fri, 02 Feb 2024 11:41:06 -0800 (PST) X-Google-Smtp-Source: AGHT+IEF/9Ld33/yAxVsGWgZxoI93erxzptUxk9tPtyDa9dyxDRrvZpFTArvK3LLfZO2O4hNVaSZOA== X-Received: by 2002:a0c:cc0c:0:b0:68c:8aaf:3536 with SMTP id r12-20020a0ccc0c000000b0068c8aaf3536mr1548236qvk.6.1706902866008; Fri, 02 Feb 2024 11:41:06 -0800 (PST) X-Forwarded-Encrypted: i=0; AJvYcCWVNmTwOvZHncsQhkfRSYNcecVf3H2Rb92a4ieFUywbnDQRswipD0Isepv1lPsUEjTKqrmo7zgVCgUkU0VUKVF/ZA== Received: from localhost.localdomain (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id mv1-20020a056214338100b0068c816c7bc5sm1060016qvb.101.2024.02.02.11.41.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 Feb 2024 11:41:05 -0800 (PST) From: Patrick Palka To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, Patrick Palka Subject: [PATCH 1/2] c++: requires-exprs and partial constraint subst [PR112769] Date: Fri, 2 Feb 2024 14:41:03 -0500 Message-ID: <20240202194104.317982-1-ppalka@redhat.com> X-Mailer: git-send-email 2.43.0.493.gbc7ee2e5e1 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-14.8 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_H5, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE 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+patchwork=sourceware.org@gcc.gnu.org Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk? -- >8 -- In r11-3261-gb28b621ac67bee we made tsubst_requires_expr never partially substitute into a requires-expression so as to avoid checking its requirements out of order during e.g. generic lambda regeneration. Unfortunately we still do need to partially substitute into a requires-expression in rare cases, in particular when it's used in associated constraints that we are directly substituting for sake of declaration matching or dguide constraint rewriting. We can identify this situation by checking processing_constraint_expression_p, so this patch uses this predicate to control whether we defer substitution or partially substitute. The entering_scope=true change in tsubst_baselink is needed to avoid ICEing from tsubst_baselink during name lookup when rewriting std::ranges::ref_view's dguide constraints. PR c++/112769 PR c++/110006 gcc/cp/ChangeLog: * constraint.cc (tsubst_simple_requirement): Return a substituted _REQ node when processing_template_decl. (tsubst_type_requirement): Likewise. (tsubst_compound_requirement): Likewise. (tsubst_nested_requirement): Likewise. (tsubst_requires_expr): Don't defer partial substitution when processing_constraint_expression_p is true, in which case return a substituted REQUIRES_EXPR. * pt.cc (tsubst_baselink): Use tsubst_aggr_type with entring_scope=true instead of tsubst to substitute qualifying_scope. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/class-deduction-alias18.C: New test. * g++.dg/cpp2a/concepts-friend16.C: New test. --- gcc/cp/constraint.cc | 38 +++++++++++++++++-- gcc/cp/pt.cc | 3 +- .../g++.dg/cpp2a/class-deduction-alias18.C | 13 +++++++ .../g++.dg/cpp2a/concepts-friend16.C | 25 ++++++++++++ 4 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/class-deduction-alias18.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-friend16.C diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index fef68cf7ab2..450ae548f9a 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -2028,6 +2028,8 @@ tsubst_simple_requirement (tree t, tree args, sat_info info) tree expr = tsubst_valid_expression_requirement (t0, args, info); if (expr == error_mark_node) return error_mark_node; + if (processing_template_decl) + return finish_simple_requirement (EXPR_LOCATION (t), expr); return boolean_true_node; } @@ -2068,6 +2070,8 @@ tsubst_type_requirement (tree t, tree args, sat_info info) tree type = tsubst_type_requirement_1 (t0, args, info, EXPR_LOCATION (t)); if (type == error_mark_node) return error_mark_node; + if (processing_template_decl) + return finish_type_requirement (EXPR_LOCATION (t), type); return boolean_true_node; } @@ -2182,6 +2186,9 @@ tsubst_compound_requirement (tree t, tree args, sat_info info) } } + if (processing_template_decl) + return finish_compound_requirement (EXPR_LOCATION (t), + expr, type, noexcept_p); return boolean_true_node; } @@ -2190,6 +2197,15 @@ tsubst_compound_requirement (tree t, tree args, sat_info info) static tree tsubst_nested_requirement (tree t, tree args, sat_info info) { + if (processing_template_decl) + { + tree req = TREE_OPERAND (t, 0); + req = tsubst_constraint (req, args, info.complain, info.in_decl); + if (req == error_mark_node) + return error_mark_node; + return finish_nested_requirement (EXPR_LOCATION (t), req); + } + sat_info quiet (tf_none, info.in_decl); tree result = constraint_satisfaction_value (t, args, quiet); if (result == boolean_true_node) @@ -2330,18 +2346,25 @@ tsubst_requires_expr (tree t, tree args, sat_info info) args = add_extra_args (REQUIRES_EXPR_EXTRA_ARGS (t), args, info.complain, info.in_decl); - if (processing_template_decl) + if (processing_template_decl + && !processing_constraint_expression_p ()) { /* We're partially instantiating a generic lambda. Substituting into this requires-expression now may cause its requirements to get checked out of order, so instead just remember the template - arguments and wait until we can substitute them all at once. */ + arguments and wait until we can substitute them all at once. + + Except if this requires-expr is part of associated constraints + that we're substituting into directly (for e.g. declaration + matching or dguide constraint rewriting), in which case we need + to partially substitute. */ t = copy_node (t); REQUIRES_EXPR_EXTRA_ARGS (t) = build_extra_args (t, args, info.complain); return t; } - if (tree parms = REQUIRES_EXPR_PARMS (t)) + tree parms = REQUIRES_EXPR_PARMS (t); + if (parms) { parms = tsubst_constraint_variables (parms, args, info); if (parms == error_mark_node) @@ -2349,10 +2372,13 @@ tsubst_requires_expr (tree t, tree args, sat_info info) } tree result = boolean_true_node; + if (processing_template_decl) + result = NULL_TREE; for (tree reqs = REQUIRES_EXPR_REQS (t); reqs; reqs = TREE_CHAIN (reqs)) { tree req = TREE_VALUE (reqs); - if (tsubst_requirement (req, args, info) == error_mark_node) + req = tsubst_requirement (req, args, info); + if (req == error_mark_node) { result = boolean_false_node; if (info.diagnose_unsatisfaction_p ()) @@ -2360,7 +2386,11 @@ tsubst_requires_expr (tree t, tree args, sat_info info) else break; } + else if (processing_template_decl) + result = tree_cons (NULL_TREE, req, result); } + if (processing_template_decl && result != boolean_false_node) + result = finish_requires_expr (EXPR_LOCATION (t), parms, nreverse (result)); return result; } diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 9d30a271713..17ecd4b9c5a 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -17065,7 +17065,8 @@ tsubst_baselink (tree baselink, tree object_type, { bool qualified_p = BASELINK_QUALIFIED_P (baselink); tree qualifying_scope = BINFO_TYPE (BASELINK_ACCESS_BINFO (baselink)); - qualifying_scope = tsubst (qualifying_scope, args, complain, in_decl); + qualifying_scope = tsubst_aggr_type (qualifying_scope, args, complain, in_decl, + /*entering_scope=*/true); tree optype = BASELINK_OPTYPE (baselink); optype = tsubst (optype, args, complain, in_decl); diff --git a/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias18.C b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias18.C new file mode 100644 index 00000000000..0bb11bb944c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias18.C @@ -0,0 +1,13 @@ +// PR c++/112769 +// { dg-do compile { target c++20 } } + +template +struct type +{ + type(T) requires requires { T{0}; }; +}; + +template +using alias = type<0, T>; + +alias foo{123}; diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-friend16.C b/gcc/testsuite/g++.dg/cpp2a/concepts-friend16.C new file mode 100644 index 00000000000..18974eeb172 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-friend16.C @@ -0,0 +1,25 @@ +// PR c++/110006 +// { dg-do compile { target c++20 } } + +template +class s; + +template +void constraint(s const&, int&); + +template +U function(s const x) + requires requires (U& u) { constraint(x, u); }; + +template +class s +{ + template + friend U function(s const x) + requires requires (U& u) { constraint(x, u); }; +}; + +int f(s q) +{ + return function(q); // { dg-bogus "ambiguous" } +}