Message ID | 20211108153550.3290787-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 BEC6E385800C for <patchwork@sourceware.org>; Mon, 8 Nov 2021 15:36:32 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BEC6E385800C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1636385792; bh=0pWH3JDO47hBvOUdEviATC4EwwADZY9BDdQNC1B6jsQ=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=DaaYbNGNzC+gPpT8vlqpYbHzUHsHe4R/6+YHJyjkOIxjamckdTWvPIv2NEdOH/3wh bpl3ybxRbPcsPaov4CV9cFzVyMnnQ2QkclEJkHatYKHmYaJvW4U2l8uBvkaVQCTvXh J0bQcRil3esgx21J5LlFkbbb2rl0GPhO/Sc7NCD4= 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 59E103858D3C for <gcc-patches@gcc.gnu.org>; Mon, 8 Nov 2021 15:36:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 59E103858D3C Received: from mail-qt1-f198.google.com (mail-qt1-f198.google.com [209.85.160.198]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-80-9-qnXfkGND-SDftdF22fVA-1; Mon, 08 Nov 2021 10:36:00 -0500 X-MC-Unique: 9-qnXfkGND-SDftdF22fVA-1 Received: by mail-qt1-f198.google.com with SMTP id 100-20020aed30ed000000b002a6b3dc6465so12105265qtf.13 for <gcc-patches@gcc.gnu.org>; Mon, 08 Nov 2021 07:36:00 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=0pWH3JDO47hBvOUdEviATC4EwwADZY9BDdQNC1B6jsQ=; b=xdnqzPlSbQ0N4EfwgfmXK3nOPjxIrE4sv8CnO+tFA/XFiAQNkhlb8HHXshCIYKtXgz 2XcLZ7ywnzlgbxN5Gvtz4s03ITTX1uLLj95/F9Hk8wHIcbHRYRtJyOhtCSJ8d6gO/KdB Ft3hOEwkjT6N9lN51yRo+9HV9fNLQfyoFlJmNrNg6vNHXCW1O5gYqcyLAxXAKKabrPLc gr6c/0/H68aDkZNFndT1CU4PQWSpBIr1jBiMIXkhuV6Qs9wwZ9nLJwIMM3q18g5nJjzh UcGA3Jrw+GWT4KQns0OHuWhsLIvtbljWARxnCJGj+hU7y/4ECfByxOmK8WQxDF1sUiYk FdXw== X-Gm-Message-State: AOAM5320fftY995YMRZRxIp10GoHpW8kXVdhG7Er+75J5oPpo/bQLw9Y PbrzQS8FRE/YeO5Gw9Qdvf3LYPvSA8JrCIyDObw4Q3wD+RrKLx3Lzrt/nWoGSE/YjklBrLwYC67 aGDFBqqQNwJdFDWbcK0pbEoLm07mafOLJQmN9RYO61HixrKtFJ7yOOg7lPGYIUV+vfOA= X-Received: by 2002:a05:622a:14a:: with SMTP id v10mr439880qtw.36.1636385759762; Mon, 08 Nov 2021 07:35:59 -0800 (PST) X-Google-Smtp-Source: ABdhPJzT16tTskg2X4PkN7khv4hwQnjQPuBUDdlACOUAU40IOnXOd8+O8MJSVCmCLT1qQzSlSKVPVQ== X-Received: by 2002:a05:622a:14a:: with SMTP id v10mr439847qtw.36.1636385759469; Mon, 08 Nov 2021 07:35:59 -0800 (PST) Received: from localhost.localdomain (ool-457d493a.dyn.optonline.net. [69.125.73.58]) by smtp.gmail.com with ESMTPSA id f34sm3037535qtb.7.2021.11.08.07.35.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Nov 2021 07:35:59 -0800 (PST) To: gcc-patches@gcc.gnu.org Subject: [PATCH] c++: bogus error w/ variadic concept-id as if cond [PR98394] Date: Mon, 8 Nov 2021 10:35:50 -0500 Message-Id: <20211108153550.3290787-1-ppalka@redhat.com> X-Mailer: git-send-email 2.34.0.rc1.14.g88d915a634 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-Spam-Status: No, score=-16.0 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list <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++: bogus error w/ variadic concept-id as if cond [PR98394]
|
|
Commit Message
Patrick Palka
Nov. 8, 2021, 3:35 p.m. UTC
Here when tentatively parsing the if condition as a declaration, we try to treat C<1> as the start of a constrained placeholder type, which we quickly reject because C doesn't accept a type as its first argument. But since we're parsing tentatively, we shouldn't emit an error in this case. Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk/11? PR c++/98394 gcc/cp/ChangeLog: * parser.c (cp_parser_placeholder_type_specifier): Don't emit a "does not constrain a type" error when parsing tentatively. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-pr98394.C: New test. --- gcc/cp/parser.c | 7 +++++-- gcc/testsuite/g++.dg/cpp2a/concepts-pr98394.C | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-pr98394.C
Comments
On 11/8/21 10:35, Patrick Palka wrote: > Here when tentatively parsing the if condition as a declaration, we try > to treat C<1> as the start of a constrained placeholder type, which we > quickly reject because C doesn't accept a type as its first argument. > But since we're parsing tentatively, we shouldn't emit an error in this > case. > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for > trunk/11? > > PR c++/98394 > > gcc/cp/ChangeLog: > > * parser.c (cp_parser_placeholder_type_specifier): Don't emit > a "does not constrain a type" error when parsing tentatively. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp2a/concepts-pr98394.C: New test. > --- > gcc/cp/parser.c | 7 +++++-- > gcc/testsuite/g++.dg/cpp2a/concepts-pr98394.C | 14 ++++++++++++++ > 2 files changed, 19 insertions(+), 2 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-pr98394.C > > diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c > index 4c2075742d6..f1498e28da4 100644 > --- a/gcc/cp/parser.c > +++ b/gcc/cp/parser.c > @@ -19909,8 +19909,11 @@ cp_parser_placeholder_type_specifier (cp_parser *parser, location_t loc, > if (!flag_concepts_ts > || !processing_template_parmlist) > { > - error_at (loc, "%qE does not constrain a type", DECL_NAME (con)); > - inform (DECL_SOURCE_LOCATION (con), "concept defined here"); > + if (!tentative) > + { > + error_at (loc, "%qE does not constrain a type", DECL_NAME (con)); > + inform (DECL_SOURCE_LOCATION (con), "concept defined here"); > + } We probably want to cp_parser_simulate_error in the tentative case? I also wonder why this code uses a "tentative" parameter instead of checking cp_parser_parsing_tentatively itself. Jason
On Mon, 8 Nov 2021, Jason Merrill wrote: > On 11/8/21 10:35, Patrick Palka wrote: > > Here when tentatively parsing the if condition as a declaration, we try > > to treat C<1> as the start of a constrained placeholder type, which we > > quickly reject because C doesn't accept a type as its first argument. > > But since we're parsing tentatively, we shouldn't emit an error in this > > case. > > > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for > > trunk/11? > > > > PR c++/98394 > > > > gcc/cp/ChangeLog: > > > > * parser.c (cp_parser_placeholder_type_specifier): Don't emit > > a "does not constrain a type" error when parsing tentatively. > > > > gcc/testsuite/ChangeLog: > > > > * g++.dg/cpp2a/concepts-pr98394.C: New test. > > --- > > gcc/cp/parser.c | 7 +++++-- > > gcc/testsuite/g++.dg/cpp2a/concepts-pr98394.C | 14 ++++++++++++++ > > 2 files changed, 19 insertions(+), 2 deletions(-) > > create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-pr98394.C > > > > diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c > > index 4c2075742d6..f1498e28da4 100644 > > --- a/gcc/cp/parser.c > > +++ b/gcc/cp/parser.c > > @@ -19909,8 +19909,11 @@ cp_parser_placeholder_type_specifier (cp_parser > > *parser, location_t loc, > > if (!flag_concepts_ts > > || !processing_template_parmlist) > > { > > - error_at (loc, "%qE does not constrain a type", DECL_NAME (con)); > > - inform (DECL_SOURCE_LOCATION (con), "concept defined here"); > > + if (!tentative) > > + { > > + error_at (loc, "%qE does not constrain a type", DECL_NAME > > (con)); > > + inform (DECL_SOURCE_LOCATION (con), "concept defined here"); > > + } > > We probably want to cp_parser_simulate_error in the tentative case? It seems the only caller, cp_parser_simple_type_specifier, is responsible for that currently. > > I also wonder why this code uses a "tentative" parameter instead of checking > cp_parser_parsing_tentatively itself. During the first call to cp_parser_placeholder_type_specifier from cp_parser_simple_type_specifier, we're always parsing tentatively so cp_parser_parsing_tentatively would always be true whereas 'tentative' could be false if there's also an outer tentative parse. So some reworking of the caller would also be needed in order to avoid the 'tentative' parameter. I tried, but I wasn't able to make it work without introducing diagnostic regressions :/ While poking at the idea though, I was reminded of the related PR85846 which is about the concept-id C<> being rejected due to a stray error being emitted during the tentative type parse. The below patch additionally fixes this PR since it just requires a one-line change in cp_parser_placeholder_type_specifier. -- >8 -- Subject: [PATCH] c++: bogus error w/ variadic concept-id as if cond [PR98394] Here when tentatively parsing the if condition as a declaration, we try to treat C<1> as the start of a constrained placeholder type, which we quickly reject because C doesn't accept a type as its first argument. But since we're parsing tentatively, we shouldn't emit an error in this case. In passing, also fix PR85846 by only overriding tentative to false when given a concept-name, and not also when given a concept-id with empty argument list. Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk/11? PR c++/98394 PR c++/85846 gcc/cp/ChangeLog: * parser.c (cp_parser_placeholder_type_specifier): Declare static. Don't override tentative to false when tmpl is a concept-id with empty argument list. Don't emit a "does not constrain a type" error when tentative. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-pr98394.C: New test. * g++.dg/cpp2a/concepts-pr85846.C: New test. --- gcc/cp/parser.c | 11 +++++++---- gcc/testsuite/g++.dg/cpp2a/concepts-pr85846.C | 5 +++++ gcc/testsuite/g++.dg/cpp2a/concepts-pr98394.C | 14 ++++++++++++++ 3 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-pr85846.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-pr98394.C diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 4c2075742d6..71f782468ef 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -19855,7 +19855,7 @@ cp_parser_simple_type_specifier (cp_parser* parser, Note that the Concepts TS allows the auto or decltype(auto) to be omitted in a constrained-type-specifier. */ -tree +static tree cp_parser_placeholder_type_specifier (cp_parser *parser, location_t loc, tree tmpl, bool tentative) { @@ -19871,7 +19871,7 @@ cp_parser_placeholder_type_specifier (cp_parser *parser, location_t loc, args = TREE_OPERAND (tmpl, 1); tmpl = TREE_OPERAND (tmpl, 0); } - if (args == NULL_TREE) + else if (args == NULL_TREE) /* A concept-name with no arguments can't be an expression. */ tentative = false; @@ -19909,8 +19909,11 @@ cp_parser_placeholder_type_specifier (cp_parser *parser, location_t loc, if (!flag_concepts_ts || !processing_template_parmlist) { - error_at (loc, "%qE does not constrain a type", DECL_NAME (con)); - inform (DECL_SOURCE_LOCATION (con), "concept defined here"); + if (!tentative) + { + error_at (loc, "%qE does not constrain a type", DECL_NAME (con)); + inform (DECL_SOURCE_LOCATION (con), "concept defined here"); + } return error_mark_node; } } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr85846.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr85846.C new file mode 100644 index 00000000000..1507c604920 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr85846.C @@ -0,0 +1,5 @@ +// PR c++/85846 +// { dg-do compile { target c++20 } } + +template<int = 0> concept Foo = true; +bool f(Foo<>); diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr98394.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr98394.C new file mode 100644 index 00000000000..c8407cdf7cd --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr98394.C @@ -0,0 +1,14 @@ +// PR c++/98394 +// { dg-do compile { target c++20 } } + +template<int...> +concept C = true; + +template<int, int> +concept D = true; + +int main() { + if (C<1>); // { dg-bogus "does not constrain a type" } + if (D<1>); // { dg-error "wrong number of template arguments" } + // { dg-bogus "does not constrain a type" "" { target *-*-* } .-1 } +}
On 11/8/21 19:54, Patrick Palka wrote: > On Mon, 8 Nov 2021, Jason Merrill wrote: > >> On 11/8/21 10:35, Patrick Palka wrote: >>> Here when tentatively parsing the if condition as a declaration, we try >>> to treat C<1> as the start of a constrained placeholder type, which we >>> quickly reject because C doesn't accept a type as its first argument. >>> But since we're parsing tentatively, we shouldn't emit an error in this >>> case. >>> >>> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for >>> trunk/11? >>> >>> PR c++/98394 >>> >>> gcc/cp/ChangeLog: >>> >>> * parser.c (cp_parser_placeholder_type_specifier): Don't emit >>> a "does not constrain a type" error when parsing tentatively. >>> >>> gcc/testsuite/ChangeLog: >>> >>> * g++.dg/cpp2a/concepts-pr98394.C: New test. >>> --- >>> gcc/cp/parser.c | 7 +++++-- >>> gcc/testsuite/g++.dg/cpp2a/concepts-pr98394.C | 14 ++++++++++++++ >>> 2 files changed, 19 insertions(+), 2 deletions(-) >>> create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-pr98394.C >>> >>> diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c >>> index 4c2075742d6..f1498e28da4 100644 >>> --- a/gcc/cp/parser.c >>> +++ b/gcc/cp/parser.c >>> @@ -19909,8 +19909,11 @@ cp_parser_placeholder_type_specifier (cp_parser >>> *parser, location_t loc, >>> if (!flag_concepts_ts >>> || !processing_template_parmlist) >>> { >>> - error_at (loc, "%qE does not constrain a type", DECL_NAME (con)); >>> - inform (DECL_SOURCE_LOCATION (con), "concept defined here"); >>> + if (!tentative) >>> + { >>> + error_at (loc, "%qE does not constrain a type", DECL_NAME >>> (con)); >>> + inform (DECL_SOURCE_LOCATION (con), "concept defined here"); >>> + } >> >> We probably want to cp_parser_simulate_error in the tentative case? > > It seems the only caller, cp_parser_simple_type_specifier, is > responsible for that currently. > >> >> I also wonder why this code uses a "tentative" parameter instead of checking >> cp_parser_parsing_tentatively itself. > > During the first call to cp_parser_placeholder_type_specifier from > cp_parser_simple_type_specifier, we're always parsing tentatively so > cp_parser_parsing_tentatively would always be true whereas 'tentative' > could be false if there's also an outer tentative parse. So some > reworking of the caller would also be needed in order to avoid the > 'tentative' parameter. I tried, but I wasn't able to make it work > without introducing diagnostic regressions :/ > > While poking at the idea though, I was reminded of the related PR85846 > which is about the concept-id C<> being rejected due to a stray error > being emitted during the tentative type parse. The below patch > additionally fixes this PR since it just requires a one-line change in > cp_parser_placeholder_type_specifier. > > -- >8 -- > > Subject: [PATCH] c++: bogus error w/ variadic concept-id as if cond [PR98394] > > Here when tentatively parsing the if condition as a declaration, we try > to treat C<1> as the start of a constrained placeholder type, which we > quickly reject because C doesn't accept a type as its first argument. > But since we're parsing tentatively, we shouldn't emit an error in this > case. > > In passing, also fix PR85846 by only overriding tentative to false when > given a concept-name, and not also when given a concept-id with empty > argument list. > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for > trunk/11? OK for both. > PR c++/98394 > PR c++/85846 > > gcc/cp/ChangeLog: > > * parser.c (cp_parser_placeholder_type_specifier): Declare > static. Don't override tentative to false when tmpl is a > concept-id with empty argument list. Don't emit a "does not > constrain a type" error when tentative. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp2a/concepts-pr98394.C: New test. > * g++.dg/cpp2a/concepts-pr85846.C: New test. > --- > gcc/cp/parser.c | 11 +++++++---- > gcc/testsuite/g++.dg/cpp2a/concepts-pr85846.C | 5 +++++ > gcc/testsuite/g++.dg/cpp2a/concepts-pr98394.C | 14 ++++++++++++++ > 3 files changed, 26 insertions(+), 4 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-pr85846.C > create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-pr98394.C > > diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c > index 4c2075742d6..71f782468ef 100644 > --- a/gcc/cp/parser.c > +++ b/gcc/cp/parser.c > @@ -19855,7 +19855,7 @@ cp_parser_simple_type_specifier (cp_parser* parser, > Note that the Concepts TS allows the auto or decltype(auto) to be > omitted in a constrained-type-specifier. */ > > -tree > +static tree > cp_parser_placeholder_type_specifier (cp_parser *parser, location_t loc, > tree tmpl, bool tentative) > { > @@ -19871,7 +19871,7 @@ cp_parser_placeholder_type_specifier (cp_parser *parser, location_t loc, > args = TREE_OPERAND (tmpl, 1); > tmpl = TREE_OPERAND (tmpl, 0); > } > - if (args == NULL_TREE) > + else if (args == NULL_TREE) > /* A concept-name with no arguments can't be an expression. */ > tentative = false; > > @@ -19909,8 +19909,11 @@ cp_parser_placeholder_type_specifier (cp_parser *parser, location_t loc, > if (!flag_concepts_ts > || !processing_template_parmlist) > { > - error_at (loc, "%qE does not constrain a type", DECL_NAME (con)); > - inform (DECL_SOURCE_LOCATION (con), "concept defined here"); > + if (!tentative) > + { > + error_at (loc, "%qE does not constrain a type", DECL_NAME (con)); > + inform (DECL_SOURCE_LOCATION (con), "concept defined here"); > + } > return error_mark_node; > } > } > diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr85846.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr85846.C > new file mode 100644 > index 00000000000..1507c604920 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr85846.C > @@ -0,0 +1,5 @@ > +// PR c++/85846 > +// { dg-do compile { target c++20 } } > + > +template<int = 0> concept Foo = true; > +bool f(Foo<>); > diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr98394.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr98394.C > new file mode 100644 > index 00000000000..c8407cdf7cd > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr98394.C > @@ -0,0 +1,14 @@ > +// PR c++/98394 > +// { dg-do compile { target c++20 } } > + > +template<int...> > +concept C = true; > + > +template<int, int> > +concept D = true; > + > +int main() { > + if (C<1>); // { dg-bogus "does not constrain a type" } > + if (D<1>); // { dg-error "wrong number of template arguments" } > + // { dg-bogus "does not constrain a type" "" { target *-*-* } .-1 } > +} >
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 4c2075742d6..f1498e28da4 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -19909,8 +19909,11 @@ cp_parser_placeholder_type_specifier (cp_parser *parser, location_t loc, if (!flag_concepts_ts || !processing_template_parmlist) { - error_at (loc, "%qE does not constrain a type", DECL_NAME (con)); - inform (DECL_SOURCE_LOCATION (con), "concept defined here"); + if (!tentative) + { + error_at (loc, "%qE does not constrain a type", DECL_NAME (con)); + inform (DECL_SOURCE_LOCATION (con), "concept defined here"); + } return error_mark_node; } } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr98394.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr98394.C new file mode 100644 index 00000000000..c8407cdf7cd --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr98394.C @@ -0,0 +1,14 @@ +// PR c++/98394 +// { dg-do compile { target c++20 } } + +template<int...> +concept C = true; + +template<int, int> +concept D = true; + +int main() { + if (C<1>); // { dg-bogus "does not constrain a type" } + if (D<1>); // { dg-error "wrong number of template arguments" } + // { dg-bogus "does not constrain a type" "" { target *-*-* } .-1 } +}