From patchwork Mon Jul 11 13:33:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 55920 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 4AB2D3858031 for ; Mon, 11 Jul 2022 13:33:45 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4AB2D3858031 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1657546425; bh=V4HrKvCM/JAvv2V7SqR+a0YMmSsqnrfpIUeNrG9jngg=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=OFahmHSVH6yzxe2gNLQwUPwF2AV3oNu6VKtcNoq+9NjPO+wWYlzDkzJ3m5R9L+34K Y5KwUDuYAArai18vQDi7eOTmS4OQqiW/rw9ydIpWajcEVt4FxkLsAxFt+hCF2Vn6xt jZ3+XI4sEGQu+fA7iWN7cn9dQEaKGfNr/cphBFxg= 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 E40973854160 for ; Mon, 11 Jul 2022 13:33:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org E40973854160 Received: from mail-qk1-f197.google.com (mail-qk1-f197.google.com [209.85.222.197]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-642-1l44tgzwP9SDNNMer_MWkw-1; Mon, 11 Jul 2022 09:33:07 -0400 X-MC-Unique: 1l44tgzwP9SDNNMer_MWkw-1 Received: by mail-qk1-f197.google.com with SMTP id l189-20020a37bbc6000000b006af2596c5e8so5370679qkf.14 for ; Mon, 11 Jul 2022 06:33:07 -0700 (PDT) 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=V4HrKvCM/JAvv2V7SqR+a0YMmSsqnrfpIUeNrG9jngg=; b=JS5FCrwhI423K3rhZa+ZzuOdOA+w5nVYVppFPejRBv0ChuUHEJOM9aMG4UTKc/kBVJ bq8WaS/7HzLwaHysb47qfZWzx0ov/TYV4AWDbZmLPm6QYQcJ+umoGZui7YdQ6bgqzrkz LIbQYO+gMl41HPSU79o8Sjgsa69hZS4gjNuPzXWCX9JbVAJkiSuyYm+XJG1U2LD7qsI7 QY6tdAaQRMUhsr4/57SIQenKkd4WilvvGGBuhdQq5d7vcSFgIpwYJd9JRob5dDJp2njD +O3xhLgiKe0OO4yGkn2ro5+c/ZC4Faiw/3E3CK/8G/2OLS4Ku08PIn/jh71XqIj5mszA 5K7Q== X-Gm-Message-State: AJIora98eXy54a7NZvXLkWbr62fTi3mTwk3Kf6uksirDzxmyCJvpAUM+ Lebq6KTwYPdPFVa/b/JEY59KQZHqNi0p7/CMEEPK2XgiopiAVT4gRvn5txDpaHY3nYz6uHCUMO5 XQSJDOmSAb7lO0KVtbbOQZKAhmkABIiLI6ZaHq660Ft7ngxGxoBY1hRUTL5ryBdd4r38= X-Received: by 2002:ac8:5fca:0:b0:31e:b661:7ae4 with SMTP id k10-20020ac85fca000000b0031eb6617ae4mr2783691qta.585.1657546386408; Mon, 11 Jul 2022 06:33:06 -0700 (PDT) X-Google-Smtp-Source: AGRyM1uJ77GqzhrCohguX2C8H7ake/SlnbSS+j9SOyM/PAunnXy5yRwMB6Pw2Odi8lR2B7ocPJcwLA== X-Received: by 2002:ac8:5fca:0:b0:31e:b661:7ae4 with SMTP id k10-20020ac85fca000000b0031eb6617ae4mr2783651qta.585.1657546386005; Mon, 11 Jul 2022 06:33:06 -0700 (PDT) Received: from localhost.localdomain (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id q27-20020a37f71b000000b006b249cc505fsm6276034qkj.82.2022.07.11.06.33.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 11 Jul 2022 06:33:05 -0700 (PDT) To: gcc-patches@gcc.gnu.org Subject: [PATCH] c++: dependence of constrained memfn from current inst [PR105842] Date: Mon, 11 Jul 2022 09:33:04 -0400 Message-Id: <20220711133304.4107913-1-ppalka@redhat.com> X-Mailer: git-send-email 2.37.0.3.g30cc8d0f14 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-14.2 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, 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.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" Here we incorrectly deem the calls to func1, func2 and tmpl2 as ambiguous ahead of time ultimately because we mishandle dependence of a constrained member function from the current instantiation. In type_dependent_expression_p, we consider the dependence of a TEMPLATE_DECL's constraints (via uses_outer_template_parms), but neglect to do the same for a FUNCTION_DECL such as func1. And in satisfy_declaration_constraints, we give up if _any_ template argument is dependent, but for non-dependent member functions from the current instantiation such as func2 and tmpl2, we can and must check constraints as long as the innermost arguments aren't dependent. Tested on x86_64-pc-linux-gnu, does this look OK for trunk/12? PR c++/105842 gcc/cp/ChangeLog: * constraint.cc (satisfy_declaration_constraints): Refine early exit test for argument dependence. * cp-tree.h (uses_outer_template_parms_in_constraints): Declare. * pt.cc (template_class_depth): Handle TI_TEMPLATE being a FIELD_DECL. (usse_outer_template_parms): Factor out constraint dependence check to ... (uses_outer_template_parms_in_constraints): ... here. (type_dependent_expression_p): Use it for FUNCTION_DECL. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-memtmpl6.C: New test. --- gcc/cp/constraint.cc | 20 +++++++---- gcc/cp/cp-tree.h | 1 + gcc/cp/pt.cc | 34 ++++++++++++++++--- .../g++.dg/cpp2a/concepts-memtmpl6.C | 34 +++++++++++++++++++ 4 files changed, 79 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-memtmpl6.C diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 591155cee22..99b97d24eae 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -3176,9 +3176,13 @@ satisfy_declaration_constraints (tree t, sat_info info) args = regen_args; } - /* If any arguments depend on template parameters, we can't - check constraints. Pretend they're satisfied for now. */ - if (uses_template_parms (args)) + /* If the innermost arguments are dependent, or if the outer arguments + are dependent and are needed by the constraints, we can't check + satisfaction yet so pretend they're satisfied for now. */ + if (uses_template_parms (args) + && (TMPL_ARGS_DEPTH (args) == 1 + || uses_template_parms (INNERMOST_TEMPLATE_ARGS (args)) + || uses_outer_template_parms_in_constraints (t))) return boolean_true_node; /* Get the normalized constraints. */ @@ -3240,9 +3244,13 @@ satisfy_declaration_constraints (tree t, tree args, sat_info info) else args = add_outermost_template_args (t, args); - /* If any arguments depend on template parameters, we can't - check constraints. Pretend they're satisfied for now. */ - if (uses_template_parms (args)) + /* If the innermost arguments are dependent, or if the outer arguments + are dependent and are needed by the constraints, we can't check + satisfaction yet so pretend they're satisfied for now. */ + if (uses_template_parms (args) + && (TMPL_ARGS_DEPTH (args) == 1 + || uses_template_parms (INNERMOST_TEMPLATE_ARGS (args)) + || uses_outer_template_parms_in_constraints (t))) return boolean_true_node; tree result = boolean_true_node; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 2fde4f83b41..bec98aa2ac3 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -7297,6 +7297,7 @@ extern tree lookup_template_function (tree, tree); extern tree lookup_template_variable (tree, tree); extern bool uses_template_parms (tree); extern bool uses_template_parms_level (tree, int); +extern bool uses_outer_template_parms_in_constraints (tree); extern bool in_template_function (void); extern bool need_generic_capture (void); extern tree instantiate_class_template (tree); diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 59ee50c152d..de5d3a5cd78 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -391,7 +391,9 @@ template_class_depth (tree type) { tree tinfo = get_template_info (type); - if (tinfo && PRIMARY_TEMPLATE_P (TI_TEMPLATE (tinfo)) + if (tinfo + && TREE_CODE (TI_TEMPLATE (tinfo)) == TEMPLATE_DECL + && PRIMARY_TEMPLATE_P (TI_TEMPLATE (tinfo)) && uses_template_parms (INNERMOST_TEMPLATE_ARGS (TI_ARGS (tinfo)))) ++depth; @@ -11011,7 +11013,7 @@ uses_template_parms_level (tree t, int level) /* Returns true if the signature of DECL depends on any template parameter from its enclosing class. */ -bool +static bool uses_outer_template_parms (tree decl) { int depth = template_class_depth (CP_DECL_CONTEXT (decl)); @@ -11042,11 +11044,27 @@ uses_outer_template_parms (tree decl) return true; } } + if (uses_outer_template_parms_in_constraints (decl)) + return true; + return false; +} + +/* Returns true if the constraints of DECL depend on any template parameters + from its enclosing scope. */ + +bool +uses_outer_template_parms_in_constraints (tree decl) +{ tree ci = get_constraints (decl); if (ci) ci = CI_ASSOCIATED_CONSTRAINTS (ci); - if (ci && for_each_template_parm (ci, template_parm_outer_level, - &depth, NULL, /*nondeduced*/true)) + if (!ci) + return false; + int depth = template_class_depth (CP_DECL_CONTEXT (decl)); + if (depth == 0) + return false; + if (for_each_template_parm (ci, template_parm_outer_level, + &depth, NULL, /*nondeduced*/true)) return true; return false; } @@ -28103,6 +28121,14 @@ type_dependent_expression_p (tree expression) return false; } + /* Otherwise, its constraints could still depend on outer template parameters + from its (dependent) scope. */ + if (TREE_CODE (expression) == FUNCTION_DECL + /* Check this sufficient condition first, as a minor optimization. */ + && !dependent_type_p (TREE_TYPE (expression)) + && uses_outer_template_parms_in_constraints (expression)) + return true; + /* Always dependent, on the number of arguments if nothing else. */ if (TREE_CODE (expression) == EXPR_PACK_EXPANSION) return true; diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-memtmpl6.C b/gcc/testsuite/g++.dg/cpp2a/concepts-memtmpl6.C new file mode 100644 index 00000000000..0e09ae6ed4c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-memtmpl6.C @@ -0,0 +1,34 @@ +// PR c++/105842 +// { dg-do compile { target c++20 } } + +template +struct S { + static void func1() requires __is_same(T, int); + static void func1() requires (!__is_same(T, int)); + + static void func2() requires false && false; + static void func2() requires false; + + template static void tmpl1() requires __is_same(T, int); + template static void tmpl1() requires (!__is_same(T, int)); + + template static void tmpl2() requires (sizeof...(Us) == 1); + template static void tmpl2() requires (sizeof...(Us) == 2); + + static void foo() { + // Both calls resolve to the first overload at instantiation time. + func1(); + tmpl1(); + } + + static void bar() { + // We can check and reject both calls ahead of time since the functions' + // constraints don't depend on outer template parameters. + func2(); // { dg-error "no match" } + tmpl2(); // { dg-error "no match" } + } +}; + +int main() { + S::foo(); +}