Message ID | 20230420153437.2910374-1-ppalka@redhat.com |
---|---|
State | New |
Headers |
Return-Path: <gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org> 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 173DD385840C for <patchwork@sourceware.org>; Thu, 20 Apr 2023 15:35:13 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 173DD385840C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1682004913; bh=Cz5SywjQnhz5NMpyBuwyHbaNFlyIIXGp9YIwMA6bbFY=; h=To:Cc:Subject:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=WZSXx3d46H5hG/rWIEce0ZJMnLJYQAYbBjCxcD/8XOJmCe8eMn9cFMwSD1CCokpav jM1YUU8ZVk8tcigXgMsEteBiCr4wzmGwN3GV/eXWZdpoqHK3Na/h3oilJ+VxMGfLwb l/4BeKPYSig3aNFzEWVxFkbuP2gRUikbwn1X6HaM= 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 ESMTPS id A5A5E3858C83 for <gcc-patches@gcc.gnu.org>; Thu, 20 Apr 2023 15:34:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A5A5E3858C83 Received: from mail-qt1-f197.google.com (mail-qt1-f197.google.com [209.85.160.197]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-333-QVNklw9bM86cRo2_PXn7eQ-1; Thu, 20 Apr 2023 11:34:40 -0400 X-MC-Unique: QVNklw9bM86cRo2_PXn7eQ-1 Received: by mail-qt1-f197.google.com with SMTP id d75a77b69052e-3ef3323e320so9917921cf.0 for <gcc-patches@gcc.gnu.org>; Thu, 20 Apr 2023 08:34:40 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682004880; x=1684596880; 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=Cz5SywjQnhz5NMpyBuwyHbaNFlyIIXGp9YIwMA6bbFY=; b=BsyxMvHquhzclkqoLl385Hpjx8KpZEGYOWI7bH56OmITUtdOyj5lfLRZqo3zzgLtF/ kRYRQeqsxy+Y+yRuRYtm9i+LIJu/tXKE0M9H0lpUnNbP2zTlFdBAZdznzZm+kEd8XBcp x8X8aO8uUrIiRIcaqjZLP6TS79OUJH1K07ulfF8OehUz/ulaTTq7fxeGh6JcX0FtIKfG UphVyjr0fqyjRVnRCCd3uWABdhztp27WAESW8K15+rt3uxXZBjxE37KohEW7f7is113i VFomk+jZyKTOw76wwkBDhzYXc1r2VzJF328ROa9R6Ja8l7+Y/z7PTy8tXlP609exqFCg Ln4w== X-Gm-Message-State: AAQBX9dw00E8HynirFyeh6pyWV85lsfHs3nL/5FmxaY/Yq7E7ZgSWU4Z SeVPJvjHpSIt5ZTNhnc2OMvSMnx1DZ93+Mao9Aj2k9VizKfsUj0vt7iZkDcl1hC2EVbryD8L+g8 IkkSC6Xr/wKePhteei6EiMSAsbzcypieFxUTmzwB/3KSotWaC1oHDfrE/evNFO5US9qiQ8EzkGM 0= X-Received: by 2002:a05:622a:50a:b0:3ed:a811:23d6 with SMTP id l10-20020a05622a050a00b003eda81123d6mr2688058qtx.57.1682004880053; Thu, 20 Apr 2023 08:34:40 -0700 (PDT) X-Google-Smtp-Source: AKy350aCPNaM9xbp+7jZf5rITAvtdFcVsPkOF+Gy2E3wvuebGP5Pi0pYVFv4l1LDBVCOYllXWhEzCA== X-Received: by 2002:a05:622a:50a:b0:3ed:a811:23d6 with SMTP id l10-20020a05622a050a00b003eda81123d6mr2687994qtx.57.1682004879462; Thu, 20 Apr 2023 08:34:39 -0700 (PDT) Received: from localhost.localdomain (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id t19-20020a374613000000b0074d02ac1c19sm521368qka.15.2023.04.20.08.34.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Apr 2023 08:34:38 -0700 (PDT) To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, Patrick Palka <ppalka@redhat.com> Subject: [PATCH] c++: improve template parameter level lowering Date: Thu, 20 Apr 2023 11:34:37 -0400 Message-ID: <20230420153437.2910374-1-ppalka@redhat.com> X-Mailer: git-send-email 2.40.0.352.g667fcf4e15 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII"; x-default=true X-Spam-Status: No, score=-13.7 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_H2, 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 <gcc-patches.gcc.gnu.org> List-Unsubscribe: <https://gcc.gnu.org/mailman/options/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe> List-Archive: <https://gcc.gnu.org/pipermail/gcc-patches/> List-Post: <mailto:gcc-patches@gcc.gnu.org> List-Help: <mailto:gcc-patches-request@gcc.gnu.org?subject=help> List-Subscribe: <https://gcc.gnu.org/mailman/listinfo/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe> From: Patrick Palka via Gcc-patches <gcc-patches@gcc.gnu.org> Reply-To: Patrick Palka <ppalka@redhat.com> Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" <gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org> |
Series |
c++: improve template parameter level lowering
|
|
Commit Message
Patrick Palka
April 20, 2023, 3:34 p.m. UTC
1. Now that we no longer substitute the constraints of an auto, we can get rid of the infinite recursion loop breaker during level lowering of a constrained auto and we can also use the TEMPLATE_PARM_DESCENDANTS cache in this case. 2. Don't bother recursing when level lowering a cv-qualified type template parameter. 3. Use TEMPLATE_PARM_DESCENDANTS when level lowering a non-type template parameter too. Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk? gcc/cp/ChangeLog: * pt.cc (tsubst) <case TEMPLATE_TYPE_PARM>: Remove infinite recursion loop breaker in the level lowering case for constrained autos. Use the TEMPLATE_PARM_DESCENDANTS cache in this case as well. <case TEMPLATE_PARM_INDEX>: Use the TEMPLATE_PARM_INDEX cache when level lowering a non-type template parameter. --- gcc/cp/pt.cc | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-)
Comments
On Thu, 20 Apr 2023, Patrick Palka wrote: > 1. Now that we no longer substitute the constraints of an auto, we can > get rid of the infinite recursion loop breaker during level lowering > of a constrained auto and we can also use the TEMPLATE_PARM_DESCENDANTS > cache in this case. > 2. Don't bother recursing when level lowering a cv-qualified type template > parameter. > 3. Use TEMPLATE_PARM_DESCENDANTS when level lowering a non-type template > parameter too. > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for > trunk? > > gcc/cp/ChangeLog: > > * pt.cc (tsubst) <case TEMPLATE_TYPE_PARM>: Remove infinite > recursion loop breaker in the level lowering case for > constrained autos. Use the TEMPLATE_PARM_DESCENDANTS cache in > this case as well. > <case TEMPLATE_PARM_INDEX>: Use the TEMPLATE_PARM_INDEX cache > when level lowering a non-type template parameter. > --- > gcc/cp/pt.cc | 42 ++++++++++++++++++++---------------------- > 1 file changed, 20 insertions(+), 22 deletions(-) > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > index f65f2d58b28..07e9736cdce 100644 > --- a/gcc/cp/pt.cc > +++ b/gcc/cp/pt.cc > @@ -16228,33 +16228,23 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) > /* If we get here, we must have been looking at a parm for a > more deeply nested template. Make a new version of this > template parameter, but with a lower level. */ > + int quals; > switch (code) > { > case TEMPLATE_TYPE_PARM: > case TEMPLATE_TEMPLATE_PARM: > - if (cp_type_quals (t)) > + quals = cp_type_quals (t); > + if (quals) > { > - r = tsubst (TYPE_MAIN_VARIANT (t), args, complain, in_decl); > - r = cp_build_qualified_type > - (r, cp_type_quals (t), > - complain | (code == TEMPLATE_TYPE_PARM > - ? tf_ignore_bad_quals : 0)); > + gcc_checking_assert (code == TEMPLATE_TYPE_PARM); > + t = TYPE_MAIN_VARIANT (t); > } > - else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM > - && PLACEHOLDER_TYPE_CONSTRAINTS_INFO (t) > - && (r = (TEMPLATE_PARM_DESCENDANTS > - (TEMPLATE_TYPE_PARM_INDEX (t)))) > - && (r = TREE_TYPE (r)) > - && !PLACEHOLDER_TYPE_CONSTRAINTS_INFO (r)) > - /* Break infinite recursion when substituting the constraints > - of a constrained placeholder. */; > - else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM > - && !PLACEHOLDER_TYPE_CONSTRAINTS_INFO (t) > - && (arg = TEMPLATE_TYPE_PARM_INDEX (t), > - r = TEMPLATE_PARM_DESCENDANTS (arg)) > - && (TEMPLATE_PARM_LEVEL (r) > - == TEMPLATE_PARM_LEVEL (arg) - levels)) > - /* Cache the simple case of lowering a type parameter. */ > + if (TREE_CODE (t) == TEMPLATE_TYPE_PARM > + && (arg = TEMPLATE_TYPE_PARM_INDEX (t), > + r = TEMPLATE_PARM_DESCENDANTS (arg)) > + && (TEMPLATE_PARM_LEVEL (r) > + == TEMPLATE_PARM_LEVEL (arg) - levels)) > + /* Cache the simple case of lowering a type parameter. */ > r = TREE_TYPE (r); > else > { > @@ -16278,6 +16268,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) > else > TYPE_CANONICAL (r) = canonical_type_parameter (r); > } > + if (quals) > + r = cp_build_qualified_type (r, quals, > + complain | tf_ignore_bad_quals); > break; > > case BOUND_TEMPLATE_TEMPLATE_PARM: > @@ -16307,7 +16300,12 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) > type = tsubst (type, args, complain, in_decl); > if (type == error_mark_node) > return error_mark_node; > - r = reduce_template_parm_level (t, type, levels, args, complain); > + if ((r = TEMPLATE_PARM_DESCENDANTS (t)) > + && (TEMPLATE_PARM_LEVEL (r) == TEMPLATE_PARM_LEVEL (t) - levels) > + && TREE_TYPE (r) == type) > + /* Cache the simple case of lowering a non-type parameter. */; > + else > + r = reduce_template_parm_level (t, type, levels, args, complain); D'oh, this hunk is totally redundant since reduce_template_parm_level already checks TEMPLATE_PARM_DESCENDANTS, and so we've been caching level-lowering of non-type template parameters this whole time. Please consider this patch instead, which removes this hunk and therefore only changes TEMPLATE_TYPE_PARM level lowering: -- >8 -- Subject: [PATCH] c++: improve TEMPLATE_TYPE_PARM level lowering 1. Don't bother recursing when level lowering a cv-qualified type template parameter. 2. Get rid of the infinite recursion loop breaker during level lowering of a constrained auto and use the TEMPLATE_PARM_DESCENDANTS cache in this case too, now that we no longer substitute its constraints. gcc/cp/ChangeLog: * pt.cc (tsubst) <case TEMPLATE_TYPE_PARM>: Don't recurse when level lowering a cv-qualified type template parameter. Remove infinite recursion loop breaker in the level lowering case for constrained autos. Use the TEMPLATE_PARM_DESCENDANTS cache in this case as well. --- gcc/cp/pt.cc | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index f65f2d58b28..ed038b9ca24 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -16228,33 +16228,23 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) /* If we get here, we must have been looking at a parm for a more deeply nested template. Make a new version of this template parameter, but with a lower level. */ + int quals; switch (code) { case TEMPLATE_TYPE_PARM: case TEMPLATE_TEMPLATE_PARM: - if (cp_type_quals (t)) + quals = cp_type_quals (t); + if (quals) { - r = tsubst (TYPE_MAIN_VARIANT (t), args, complain, in_decl); - r = cp_build_qualified_type - (r, cp_type_quals (t), - complain | (code == TEMPLATE_TYPE_PARM - ? tf_ignore_bad_quals : 0)); + gcc_checking_assert (code == TEMPLATE_TYPE_PARM); + t = TYPE_MAIN_VARIANT (t); } - else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM - && PLACEHOLDER_TYPE_CONSTRAINTS_INFO (t) - && (r = (TEMPLATE_PARM_DESCENDANTS - (TEMPLATE_TYPE_PARM_INDEX (t)))) - && (r = TREE_TYPE (r)) - && !PLACEHOLDER_TYPE_CONSTRAINTS_INFO (r)) - /* Break infinite recursion when substituting the constraints - of a constrained placeholder. */; - else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM - && !PLACEHOLDER_TYPE_CONSTRAINTS_INFO (t) - && (arg = TEMPLATE_TYPE_PARM_INDEX (t), - r = TEMPLATE_PARM_DESCENDANTS (arg)) - && (TEMPLATE_PARM_LEVEL (r) - == TEMPLATE_PARM_LEVEL (arg) - levels)) - /* Cache the simple case of lowering a type parameter. */ + if (TREE_CODE (t) == TEMPLATE_TYPE_PARM + && (arg = TEMPLATE_TYPE_PARM_INDEX (t), + r = TEMPLATE_PARM_DESCENDANTS (arg)) + && (TEMPLATE_PARM_LEVEL (r) + == TEMPLATE_PARM_LEVEL (arg) - levels)) + /* Cache the simple case of lowering a type parameter. */ r = TREE_TYPE (r); else { @@ -16278,6 +16268,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) else TYPE_CANONICAL (r) = canonical_type_parameter (r); } + if (quals) + r = cp_build_qualified_type (r, quals, + complain | tf_ignore_bad_quals); break; case BOUND_TEMPLATE_TEMPLATE_PARM:
On 4/20/23 11:44, Patrick Palka wrote: > On Thu, 20 Apr 2023, Patrick Palka wrote: > >> 1. Now that we no longer substitute the constraints of an auto, we can >> get rid of the infinite recursion loop breaker during level lowering >> of a constrained auto and we can also use the TEMPLATE_PARM_DESCENDANTS >> cache in this case. >> 2. Don't bother recursing when level lowering a cv-qualified type template >> parameter. >> 3. Use TEMPLATE_PARM_DESCENDANTS when level lowering a non-type template >> parameter too. >> >> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for >> trunk? >> >> gcc/cp/ChangeLog: >> >> * pt.cc (tsubst) <case TEMPLATE_TYPE_PARM>: Remove infinite >> recursion loop breaker in the level lowering case for >> constrained autos. Use the TEMPLATE_PARM_DESCENDANTS cache in >> this case as well. >> <case TEMPLATE_PARM_INDEX>: Use the TEMPLATE_PARM_INDEX cache >> when level lowering a non-type template parameter. >> --- >> gcc/cp/pt.cc | 42 ++++++++++++++++++++---------------------- >> 1 file changed, 20 insertions(+), 22 deletions(-) >> >> diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc >> index f65f2d58b28..07e9736cdce 100644 >> --- a/gcc/cp/pt.cc >> +++ b/gcc/cp/pt.cc >> @@ -16228,33 +16228,23 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) >> /* If we get here, we must have been looking at a parm for a >> more deeply nested template. Make a new version of this >> template parameter, but with a lower level. */ >> + int quals; >> switch (code) >> { >> case TEMPLATE_TYPE_PARM: >> case TEMPLATE_TEMPLATE_PARM: >> - if (cp_type_quals (t)) >> + quals = cp_type_quals (t); >> + if (quals) >> { >> - r = tsubst (TYPE_MAIN_VARIANT (t), args, complain, in_decl); >> - r = cp_build_qualified_type >> - (r, cp_type_quals (t), >> - complain | (code == TEMPLATE_TYPE_PARM >> - ? tf_ignore_bad_quals : 0)); >> + gcc_checking_assert (code == TEMPLATE_TYPE_PARM); >> + t = TYPE_MAIN_VARIANT (t); >> } >> - else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM >> - && PLACEHOLDER_TYPE_CONSTRAINTS_INFO (t) >> - && (r = (TEMPLATE_PARM_DESCENDANTS >> - (TEMPLATE_TYPE_PARM_INDEX (t)))) >> - && (r = TREE_TYPE (r)) >> - && !PLACEHOLDER_TYPE_CONSTRAINTS_INFO (r)) >> - /* Break infinite recursion when substituting the constraints >> - of a constrained placeholder. */; >> - else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM >> - && !PLACEHOLDER_TYPE_CONSTRAINTS_INFO (t) >> - && (arg = TEMPLATE_TYPE_PARM_INDEX (t), >> - r = TEMPLATE_PARM_DESCENDANTS (arg)) >> - && (TEMPLATE_PARM_LEVEL (r) >> - == TEMPLATE_PARM_LEVEL (arg) - levels)) >> - /* Cache the simple case of lowering a type parameter. */ >> + if (TREE_CODE (t) == TEMPLATE_TYPE_PARM >> + && (arg = TEMPLATE_TYPE_PARM_INDEX (t), >> + r = TEMPLATE_PARM_DESCENDANTS (arg)) >> + && (TEMPLATE_PARM_LEVEL (r) >> + == TEMPLATE_PARM_LEVEL (arg) - levels)) >> + /* Cache the simple case of lowering a type parameter. */ >> r = TREE_TYPE (r); >> else >> { >> @@ -16278,6 +16268,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) >> else >> TYPE_CANONICAL (r) = canonical_type_parameter (r); >> } >> + if (quals) >> + r = cp_build_qualified_type (r, quals, >> + complain | tf_ignore_bad_quals); >> break; >> >> case BOUND_TEMPLATE_TEMPLATE_PARM: >> @@ -16307,7 +16300,12 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) >> type = tsubst (type, args, complain, in_decl); >> if (type == error_mark_node) >> return error_mark_node; >> - r = reduce_template_parm_level (t, type, levels, args, complain); >> + if ((r = TEMPLATE_PARM_DESCENDANTS (t)) >> + && (TEMPLATE_PARM_LEVEL (r) == TEMPLATE_PARM_LEVEL (t) - levels) >> + && TREE_TYPE (r) == type) >> + /* Cache the simple case of lowering a non-type parameter. */; >> + else >> + r = reduce_template_parm_level (t, type, levels, args, complain); > > D'oh, this hunk is totally redundant since reduce_template_parm_level > already checks TEMPLATE_PARM_DESCENDANTS, and so we've been caching > level-lowering of non-type template parameters this whole time. > > Please consider this patch instead, which removes this hunk and > therefore only changes TEMPLATE_TYPE_PARM level lowering: OK. > -- >8 -- > > Subject: [PATCH] c++: improve TEMPLATE_TYPE_PARM level lowering > > 1. Don't bother recursing when level lowering a cv-qualified type template > parameter. > 2. Get rid of the infinite recursion loop breaker during level lowering of > a constrained auto and use the TEMPLATE_PARM_DESCENDANTS cache in this > case too, now that we no longer substitute its constraints. > > gcc/cp/ChangeLog: > > * pt.cc (tsubst) <case TEMPLATE_TYPE_PARM>: Don't recurse when > level lowering a cv-qualified type template parameter. Remove > infinite recursion loop breaker in the level lowering case for > constrained autos. Use the TEMPLATE_PARM_DESCENDANTS cache in > this case as well. > --- > gcc/cp/pt.cc | 35 ++++++++++++++--------------------- > 1 file changed, 14 insertions(+), 21 deletions(-) > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > index f65f2d58b28..ed038b9ca24 100644 > --- a/gcc/cp/pt.cc > +++ b/gcc/cp/pt.cc > @@ -16228,33 +16228,23 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) > /* If we get here, we must have been looking at a parm for a > more deeply nested template. Make a new version of this > template parameter, but with a lower level. */ > + int quals; > switch (code) > { > case TEMPLATE_TYPE_PARM: > case TEMPLATE_TEMPLATE_PARM: > - if (cp_type_quals (t)) > + quals = cp_type_quals (t); > + if (quals) > { > - r = tsubst (TYPE_MAIN_VARIANT (t), args, complain, in_decl); > - r = cp_build_qualified_type > - (r, cp_type_quals (t), > - complain | (code == TEMPLATE_TYPE_PARM > - ? tf_ignore_bad_quals : 0)); > + gcc_checking_assert (code == TEMPLATE_TYPE_PARM); > + t = TYPE_MAIN_VARIANT (t); > } > - else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM > - && PLACEHOLDER_TYPE_CONSTRAINTS_INFO (t) > - && (r = (TEMPLATE_PARM_DESCENDANTS > - (TEMPLATE_TYPE_PARM_INDEX (t)))) > - && (r = TREE_TYPE (r)) > - && !PLACEHOLDER_TYPE_CONSTRAINTS_INFO (r)) > - /* Break infinite recursion when substituting the constraints > - of a constrained placeholder. */; > - else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM > - && !PLACEHOLDER_TYPE_CONSTRAINTS_INFO (t) > - && (arg = TEMPLATE_TYPE_PARM_INDEX (t), > - r = TEMPLATE_PARM_DESCENDANTS (arg)) > - && (TEMPLATE_PARM_LEVEL (r) > - == TEMPLATE_PARM_LEVEL (arg) - levels)) > - /* Cache the simple case of lowering a type parameter. */ > + if (TREE_CODE (t) == TEMPLATE_TYPE_PARM > + && (arg = TEMPLATE_TYPE_PARM_INDEX (t), > + r = TEMPLATE_PARM_DESCENDANTS (arg)) > + && (TEMPLATE_PARM_LEVEL (r) > + == TEMPLATE_PARM_LEVEL (arg) - levels)) > + /* Cache the simple case of lowering a type parameter. */ > r = TREE_TYPE (r); > else > { > @@ -16278,6 +16268,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) > else > TYPE_CANONICAL (r) = canonical_type_parameter (r); > } > + if (quals) > + r = cp_build_qualified_type (r, quals, > + complain | tf_ignore_bad_quals); > break; > > case BOUND_TEMPLATE_TEMPLATE_PARM:
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index f65f2d58b28..07e9736cdce 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -16228,33 +16228,23 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) /* If we get here, we must have been looking at a parm for a more deeply nested template. Make a new version of this template parameter, but with a lower level. */ + int quals; switch (code) { case TEMPLATE_TYPE_PARM: case TEMPLATE_TEMPLATE_PARM: - if (cp_type_quals (t)) + quals = cp_type_quals (t); + if (quals) { - r = tsubst (TYPE_MAIN_VARIANT (t), args, complain, in_decl); - r = cp_build_qualified_type - (r, cp_type_quals (t), - complain | (code == TEMPLATE_TYPE_PARM - ? tf_ignore_bad_quals : 0)); + gcc_checking_assert (code == TEMPLATE_TYPE_PARM); + t = TYPE_MAIN_VARIANT (t); } - else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM - && PLACEHOLDER_TYPE_CONSTRAINTS_INFO (t) - && (r = (TEMPLATE_PARM_DESCENDANTS - (TEMPLATE_TYPE_PARM_INDEX (t)))) - && (r = TREE_TYPE (r)) - && !PLACEHOLDER_TYPE_CONSTRAINTS_INFO (r)) - /* Break infinite recursion when substituting the constraints - of a constrained placeholder. */; - else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM - && !PLACEHOLDER_TYPE_CONSTRAINTS_INFO (t) - && (arg = TEMPLATE_TYPE_PARM_INDEX (t), - r = TEMPLATE_PARM_DESCENDANTS (arg)) - && (TEMPLATE_PARM_LEVEL (r) - == TEMPLATE_PARM_LEVEL (arg) - levels)) - /* Cache the simple case of lowering a type parameter. */ + if (TREE_CODE (t) == TEMPLATE_TYPE_PARM + && (arg = TEMPLATE_TYPE_PARM_INDEX (t), + r = TEMPLATE_PARM_DESCENDANTS (arg)) + && (TEMPLATE_PARM_LEVEL (r) + == TEMPLATE_PARM_LEVEL (arg) - levels)) + /* Cache the simple case of lowering a type parameter. */ r = TREE_TYPE (r); else { @@ -16278,6 +16268,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) else TYPE_CANONICAL (r) = canonical_type_parameter (r); } + if (quals) + r = cp_build_qualified_type (r, quals, + complain | tf_ignore_bad_quals); break; case BOUND_TEMPLATE_TEMPLATE_PARM: @@ -16307,7 +16300,12 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) type = tsubst (type, args, complain, in_decl); if (type == error_mark_node) return error_mark_node; - r = reduce_template_parm_level (t, type, levels, args, complain); + if ((r = TEMPLATE_PARM_DESCENDANTS (t)) + && (TEMPLATE_PARM_LEVEL (r) == TEMPLATE_PARM_LEVEL (t) - levels) + && TREE_TYPE (r) == type) + /* Cache the simple case of lowering a non-type parameter. */; + else + r = reduce_template_parm_level (t, type, levels, args, complain); break; default: