Message ID | 20221216164526.224772-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 3C45738388E1 for <patchwork@sourceware.org>; Fri, 16 Dec 2022 16:46:19 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3C45738388E1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1671209179; bh=P5Gi83cMJBRoBZirDT9bD4tmhxh6HtnWZmUVEMfrZXM=; h=To:Cc:Subject:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=TTUOcqReNd/a3WxlhQEHncCzjXt6gT9ivD88m7jRCglUBRgTGimnyaQppsyjgLN0y Cr39v343v8cROBihxjE8Gcg8gsdXypvJetxalnYCLSUjsawhquEfIpwYoJW7CdUkJw rHfVwEwOUsMGD0LelTdkBBM9M5Lv/aSpAyQ6MYiQ= 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 EEAA438500A6 for <gcc-patches@gcc.gnu.org>; Fri, 16 Dec 2022 16:45:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org EEAA438500A6 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_128_GCM_SHA256) id us-mta-622-f9CLqzahO-OkVXzF8CztZg-1; Fri, 16 Dec 2022 11:45:30 -0500 X-MC-Unique: f9CLqzahO-OkVXzF8CztZg-1 Received: by mail-qv1-f72.google.com with SMTP id s9-20020a0cf789000000b004d544bd8258so1751578qvn.16 for <gcc-patches@gcc.gnu.org>; Fri, 16 Dec 2022 08:45:30 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=P5Gi83cMJBRoBZirDT9bD4tmhxh6HtnWZmUVEMfrZXM=; b=w9a2r9F61lHmNNoA5eLTwcboeSSub4XYOwJbdV8p7ON2oXxo/PIF3GREgaHaM79Gh6 YsziJvq7cotcUc2DTLTUjZG3vm8cDASXCFcKBbXUCDOhea4qMD31wBrm5552wkIODWeE NXVaMZo93tibyoB6B0xyVHY4aeGw6NscybsH9+W57NNC5KdaoZHvfKCixfnYA+lm+CbM e+8aTznGP0wO9HiiT79X+baJ7l9rPemKNcbXlfC7n6SJCvjEIqPypLkrWK8wk2a22LEC 576u9bYseaLvojinoGCSCQFOzZAs7to+Pc9iUXMMnLQ65RZ8xA5paXvHJzWJOeRKGjCJ Hp5w== X-Gm-Message-State: ANoB5pnhaAP4io5MJh5zoUC4f29YcbSP5maVlIaa8hbgZ7wBon0VkcSK NChZMkVYbccal2uArbYKmerCWcYuzOkF9yC+xoFdwlMFCPsq/0bchii0VnIWZBDmGheAvpu38kf KkYccHJwumC4+ybtyvpMZWQkd2/uiioLnzLN5cSDU8Rt1E/csW3cCWeWJKScEZRfLHyk= X-Received: by 2002:a05:622a:1e18:b0:3a7:e619:61a with SMTP id br24-20020a05622a1e1800b003a7e619061amr41854568qtb.37.1671209129662; Fri, 16 Dec 2022 08:45:29 -0800 (PST) X-Google-Smtp-Source: AA0mqf5bhki3oQTm87Z4ji/dX+H/3nWhQ7UYH35m6QJQM8hR3hkc6k155UscUoD7b09j0HFXb15WJQ== X-Received: by 2002:a05:622a:1e18:b0:3a7:e619:61a with SMTP id br24-20020a05622a1e1800b003a7e619061amr41854534qtb.37.1671209129245; Fri, 16 Dec 2022 08:45:29 -0800 (PST) Received: from localhost.localdomain (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id m9-20020a05620a290900b006fa8299b4d5sm1847600qkp.100.2022.12.16.08.45.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Dec 2022 08:45:28 -0800 (PST) To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, Patrick Palka <ppalka@redhat.com> Subject: [PATCH] c++: empty captured var as template argument [PR107437] Date: Fri, 16 Dec 2022 11:45:26 -0500 Message-Id: <20221216164526.224772-1-ppalka@redhat.com> X-Mailer: git-send-email 2.39.0.56.g57e2c6ebbe 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 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++: empty captured var as template argument [PR107437]
|
|
Commit Message
Patrick Palka
Dec. 16, 2022, 4:45 p.m. UTC
Here we're rejecting the use of the captured 't' (of empty type) as a template argument ultimately because convert_nontype_argument checks potentiality using is_constant_expression which returns false for captured variables since want_rval=false. But in this case an lvalue-to-rvalue conversion of the argument is implied, so I believe we should be checking is_rvalue_constant_expression. This patch defines an rvalue version of is_nondep_const_expr and uses it in convert_nontype_argument when the target type is a non-reference. Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look right? Alternatively, since 'non_dep' in convert_nontype_argument controls only whether we should call instantiate_non_dependent_expr, it seems weird to me that we care about potentiality at all. So I experimented with using instantiation_dependent_expression_p here instead, and that seemed to work well and even fixed the dg-ice'd test cpp1z/constexpr-lambda26.C. In r12-7564-gec0f53a3a542e7 we made a similar change to decltype. PR c++/107437 gcc/cp/ChangeLog: * constexpr.cc (is_nondependent_rvalue_constant_expression): Define. * cp-tree.h (is_nondependent_rvalue_constant_expression): Declare. * pt.cc (convert_nontype_argument): Use it instead of the non-rvalue version when converting to a non-reference type. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/lambda-generic-107437.C: New test. --- gcc/cp/constexpr.cc | 10 +++++++++ gcc/cp/cp-tree.h | 1 + gcc/cp/pt.cc | 4 +++- .../g++.dg/cpp1y/lambda-generic-107437.C | 22 +++++++++++++++++++ 4 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp1y/lambda-generic-107437.C
Comments
On 12/16/22 11:45, Patrick Palka wrote: > Here we're rejecting the use of the captured 't' (of empty type) as a > template argument ultimately because convert_nontype_argument checks > potentiality using is_constant_expression which returns false for > captured variables since want_rval=false. But in this case an > lvalue-to-rvalue conversion of the argument is implied, so I believe we > should be checking is_rvalue_constant_expression. > > This patch defines an rvalue version of is_nondep_const_expr and uses > it in convert_nontype_argument when the target type is a non-reference. > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look right? > Alternatively, since 'non_dep' in convert_nontype_argument controls only > whether we should call instantiate_non_dependent_expr, it seems weird to > me that we care about potentiality at all. So I experimented with using > instantiation_dependent_expression_p here instead, and that seemed to > work well and even fixed the dg-ice'd test cpp1z/constexpr-lambda26.C. > In r12-7564-gec0f53a3a542e7 we made a similar change to decltype. This approach sounds good to me. > PR c++/107437 > > gcc/cp/ChangeLog: > > * constexpr.cc (is_nondependent_rvalue_constant_expression): > Define. > * cp-tree.h (is_nondependent_rvalue_constant_expression): > Declare. > * pt.cc (convert_nontype_argument): Use it instead of the > non-rvalue version when converting to a non-reference type. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp1y/lambda-generic-107437.C: New test. > --- > gcc/cp/constexpr.cc | 10 +++++++++ > gcc/cp/cp-tree.h | 1 + > gcc/cp/pt.cc | 4 +++- > .../g++.dg/cpp1y/lambda-generic-107437.C | 22 +++++++++++++++++++ > 4 files changed, 36 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/g++.dg/cpp1y/lambda-generic-107437.C > > diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc > index e43d92864f5..77e0e261cca 100644 > --- a/gcc/cp/constexpr.cc > +++ b/gcc/cp/constexpr.cc > @@ -10139,6 +10139,16 @@ is_nondependent_constant_expression (tree t) > && !instantiation_dependent_expression_p (t)); > } > > +/* As above, but expect an rvalue. */ > + > +bool > +is_nondependent_rvalue_constant_expression (tree t) > +{ > + return (!type_unknown_p (t) > + && is_rvalue_constant_expression (t) > + && !instantiation_dependent_expression_p (t)); > +} > + > /* Returns true if T is a potential static initializer expression that is not > instantiation-dependent. */ > > diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h > index 0d6c234b3b0..2d4c5cc3ebd 100644 > --- a/gcc/cp/cp-tree.h > +++ b/gcc/cp/cp-tree.h > @@ -8471,6 +8471,7 @@ extern bool potential_constant_expression (tree); > extern bool is_constant_expression (tree); > extern bool is_rvalue_constant_expression (tree); > extern bool is_nondependent_constant_expression (tree); > +extern bool is_nondependent_rvalue_constant_expression (tree); > extern bool is_nondependent_static_init_expression (tree); > extern bool is_static_init_expression (tree); > extern bool is_std_allocator (tree); > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > index bc566ab702b..87caea5f202 100644 > --- a/gcc/cp/pt.cc > +++ b/gcc/cp/pt.cc > @@ -7318,7 +7318,9 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) > && has_value_dependent_address (expr)) > /* If we want the address and it's value-dependent, don't fold. */; > else if (processing_template_decl > - && is_nondependent_constant_expression (expr)) > + && (TYPE_REF_P (type) > + ? is_nondependent_constant_expression (expr) > + : is_nondependent_rvalue_constant_expression (expr))) > non_dep = true; > if (error_operand_p (expr)) > return error_mark_node; > diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-107437.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-107437.C > new file mode 100644 > index 00000000000..934f863659d > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-107437.C > @@ -0,0 +1,22 @@ > +// PR c++/107437 > +// { dg-do compile { target c++11 } } > + > +struct integral_constant { > + constexpr operator int() const { return 42; } > +}; > + > +template<int N> > +struct A { > + static constexpr int value = N; > +}; > + > +template<class T> > +void f(T t) { > + [=](auto) { > + A<t> a; // { dg-bogus "constant" } > + return a.value; > + }(0); > +} > + > +template void f(integral_constant); > +
On Fri, 16 Dec 2022, Jason Merrill wrote: > On 12/16/22 11:45, Patrick Palka wrote: > > Here we're rejecting the use of the captured 't' (of empty type) as a > > template argument ultimately because convert_nontype_argument checks > > potentiality using is_constant_expression which returns false for > > captured variables since want_rval=false. But in this case an > > lvalue-to-rvalue conversion of the argument is implied, so I believe we > > should be checking is_rvalue_constant_expression. > > > > This patch defines an rvalue version of is_nondep_const_expr and uses > > it in convert_nontype_argument when the target type is a non-reference. > > > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look right? > > Alternatively, since 'non_dep' in convert_nontype_argument controls only > > whether we should call instantiate_non_dependent_expr, it seems weird to > > me that we care about potentiality at all. So I experimented with using > > instantiation_dependent_expression_p here instead, and that seemed to > > work well and even fixed the dg-ice'd test cpp1z/constexpr-lambda26.C. > > In r12-7564-gec0f53a3a542e7 we made a similar change to decltype. > > This approach sounds good to me. Like so? Bootstrapped and regtested on x86_64-pc-linux-gnu. -- >8 -- Subject: [PATCH] c++: constantness of non-dependent NTTP argument [PR107437] Here we're rejecting the use of the captured 't' (of empty type) as a template argument ultimately because convert_nontype_argument checks constantness using is_constant_expression which returns false for captured variables since want_rval=false. But in this case an lvalue-to-rvalue conversion of the argument is implied, so I believe we should be using is_rvalue_constant_expression instead. However, it doesn't seem necessary to consider constantness at all in convert_nontype_argument when determining whether to instantiate a non-dependent argument. So this patch gets rid of the problematic constantness test altogether, which is sufficient to fix the testcase (as well as the similar dg-ice'd testcase from PR87765). Note that in r12-7564-gec0f53a3a542e7 we made a similar change to finish_decltype_type. PR c++/107437 PR c++/87765 gcc/cp/ChangeLog: * pt.cc (convert_nontype_argument): Relax is_nondep_const_expr test to !inst_dep_expr_p. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/lambda-generic-107437.C: New test. * g++.dg/cpp1z/constexpr-lambda26.C: Remove dg-ice. --- gcc/cp/pt.cc | 2 +- .../g++.dg/cpp1y/lambda-generic-107437.C | 21 +++++++++++++++++++ .../g++.dg/cpp1z/constexpr-lambda26.C | 1 - 3 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1y/lambda-generic-107437.C diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index bc566ab702b..2516cca590e 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -7318,7 +7318,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) && has_value_dependent_address (expr)) /* If we want the address and it's value-dependent, don't fold. */; else if (processing_template_decl - && is_nondependent_constant_expression (expr)) + && !instantiation_dependent_expression_p (expr)) non_dep = true; if (error_operand_p (expr)) return error_mark_node; diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-107437.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-107437.C new file mode 100644 index 00000000000..f9b4e0187e2 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-107437.C @@ -0,0 +1,21 @@ +// PR c++/107437 +// { dg-do compile { target c++14 } } + +struct integral_constant { + constexpr operator int() const { return 42; } +}; + +template<int N> +struct A { + static constexpr int value = N; +}; + +template<class T> +void f(T t) { + [=](auto) { + A<t> a; // { dg-bogus "constant" } + return a.value; + }(0); +} + +template void f(integral_constant); diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda26.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda26.C index 0cdb400d21c..e66cd1dee64 100644 --- a/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda26.C +++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda26.C @@ -1,7 +1,6 @@ // PR c++/87765 // { dg-do compile { target c++17 } } // { dg-additional-options "-fchecking" } -// { dg-ice "cxx_eval_constant_expression" } template <int N> using foo = int;
On 12/16/22 14:03, Patrick Palka wrote: > On Fri, 16 Dec 2022, Jason Merrill wrote: > >> On 12/16/22 11:45, Patrick Palka wrote: >>> Here we're rejecting the use of the captured 't' (of empty type) as a >>> template argument ultimately because convert_nontype_argument checks >>> potentiality using is_constant_expression which returns false for >>> captured variables since want_rval=false. But in this case an >>> lvalue-to-rvalue conversion of the argument is implied, so I believe we >>> should be checking is_rvalue_constant_expression. >>> >>> This patch defines an rvalue version of is_nondep_const_expr and uses >>> it in convert_nontype_argument when the target type is a non-reference. >>> >>> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look right? >>> Alternatively, since 'non_dep' in convert_nontype_argument controls only >>> whether we should call instantiate_non_dependent_expr, it seems weird to >>> me that we care about potentiality at all. So I experimented with using >>> instantiation_dependent_expression_p here instead, and that seemed to >>> work well and even fixed the dg-ice'd test cpp1z/constexpr-lambda26.C. >>> In r12-7564-gec0f53a3a542e7 we made a similar change to decltype. >> >> This approach sounds good to me. > > Like so? Bootstrapped and regtested on x86_64-pc-linux-gnu. OK. > -- >8 -- > > Subject: [PATCH] c++: constantness of non-dependent NTTP argument [PR107437] > > Here we're rejecting the use of the captured 't' (of empty type) as a > template argument ultimately because convert_nontype_argument checks > constantness using is_constant_expression which returns false for > captured variables since want_rval=false. But in this case an > lvalue-to-rvalue conversion of the argument is implied, so I believe we > should be using is_rvalue_constant_expression instead. > > However, it doesn't seem necessary to consider constantness at all > in convert_nontype_argument when determining whether to instantiate > a non-dependent argument. So this patch gets rid of the problematic > constantness test altogether, which is sufficient to fix the testcase > (as well as the similar dg-ice'd testcase from PR87765). Note that in > r12-7564-gec0f53a3a542e7 we made a similar change to finish_decltype_type. > > PR c++/107437 > PR c++/87765 > > gcc/cp/ChangeLog: > > * pt.cc (convert_nontype_argument): Relax is_nondep_const_expr > test to !inst_dep_expr_p. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp1y/lambda-generic-107437.C: New test. > * g++.dg/cpp1z/constexpr-lambda26.C: Remove dg-ice. > --- > gcc/cp/pt.cc | 2 +- > .../g++.dg/cpp1y/lambda-generic-107437.C | 21 +++++++++++++++++++ > .../g++.dg/cpp1z/constexpr-lambda26.C | 1 - > 3 files changed, 22 insertions(+), 2 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/cpp1y/lambda-generic-107437.C > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > index bc566ab702b..2516cca590e 100644 > --- a/gcc/cp/pt.cc > +++ b/gcc/cp/pt.cc > @@ -7318,7 +7318,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) > && has_value_dependent_address (expr)) > /* If we want the address and it's value-dependent, don't fold. */; > else if (processing_template_decl > - && is_nondependent_constant_expression (expr)) > + && !instantiation_dependent_expression_p (expr)) > non_dep = true; > if (error_operand_p (expr)) > return error_mark_node; > diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-107437.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-107437.C > new file mode 100644 > index 00000000000..f9b4e0187e2 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-107437.C > @@ -0,0 +1,21 @@ > +// PR c++/107437 > +// { dg-do compile { target c++14 } } > + > +struct integral_constant { > + constexpr operator int() const { return 42; } > +}; > + > +template<int N> > +struct A { > + static constexpr int value = N; > +}; > + > +template<class T> > +void f(T t) { > + [=](auto) { > + A<t> a; // { dg-bogus "constant" } > + return a.value; > + }(0); > +} > + > +template void f(integral_constant); > diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda26.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda26.C > index 0cdb400d21c..e66cd1dee64 100644 > --- a/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda26.C > +++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda26.C > @@ -1,7 +1,6 @@ > // PR c++/87765 > // { dg-do compile { target c++17 } } > // { dg-additional-options "-fchecking" } > -// { dg-ice "cxx_eval_constant_expression" } > > template <int N> > using foo = int;
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index e43d92864f5..77e0e261cca 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -10139,6 +10139,16 @@ is_nondependent_constant_expression (tree t) && !instantiation_dependent_expression_p (t)); } +/* As above, but expect an rvalue. */ + +bool +is_nondependent_rvalue_constant_expression (tree t) +{ + return (!type_unknown_p (t) + && is_rvalue_constant_expression (t) + && !instantiation_dependent_expression_p (t)); +} + /* Returns true if T is a potential static initializer expression that is not instantiation-dependent. */ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 0d6c234b3b0..2d4c5cc3ebd 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -8471,6 +8471,7 @@ extern bool potential_constant_expression (tree); extern bool is_constant_expression (tree); extern bool is_rvalue_constant_expression (tree); extern bool is_nondependent_constant_expression (tree); +extern bool is_nondependent_rvalue_constant_expression (tree); extern bool is_nondependent_static_init_expression (tree); extern bool is_static_init_expression (tree); extern bool is_std_allocator (tree); diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index bc566ab702b..87caea5f202 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -7318,7 +7318,9 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) && has_value_dependent_address (expr)) /* If we want the address and it's value-dependent, don't fold. */; else if (processing_template_decl - && is_nondependent_constant_expression (expr)) + && (TYPE_REF_P (type) + ? is_nondependent_constant_expression (expr) + : is_nondependent_rvalue_constant_expression (expr))) non_dep = true; if (error_operand_p (expr)) return error_mark_node; diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-107437.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-107437.C new file mode 100644 index 00000000000..934f863659d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-107437.C @@ -0,0 +1,22 @@ +// PR c++/107437 +// { dg-do compile { target c++11 } } + +struct integral_constant { + constexpr operator int() const { return 42; } +}; + +template<int N> +struct A { + static constexpr int value = N; +}; + +template<class T> +void f(T t) { + [=](auto) { + A<t> a; // { dg-bogus "constant" } + return a.value; + }(0); +} + +template void f(integral_constant); +