Re: [PATCH] c++: Reject identifier label in constexpr [PR97846]
On Fri, Nov 20, 2020 at 05:18:55PM -0500, Jason Merrill via Gcc-patches wrote: > On 11/16/20 9:58 PM, Marek Polacek wrote: > > [dcl.constexpr]/3 says that the function-body of a constexpr function > > shall not contain an identifier label, but we aren't enforcing that. > > > > This patch implements that. Of course, we can't reject artificial > > labels. > > > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? > > > > gcc/cp/ChangeLog: > > > > PR c++/97846 > > * constexpr.c (potential_constant_expression_1): Reject > > LABEL_EXPRs that use non-artifical LABEL_DECLs. > > > > gcc/testsuite/ChangeLog: > > > > PR c++/97846 > > * g++.dg/cpp1y/constexpr-label.C: New test. > > --- > > gcc/cp/constexpr.c | 9 - > > gcc/testsuite/g++.dg/cpp1y/constexpr-label.C | 9 + > > 2 files changed, 17 insertions(+), 1 deletion(-) > > create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-label.C > > > > diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c > > index e6ab5eecd68..e4fbce14065 100644 > > --- a/gcc/cp/constexpr.c > > +++ b/gcc/cp/constexpr.c > > @@ -7484,7 +7484,6 @@ potential_constant_expression_1 (tree t, bool > > want_rval, bool strict, bool now, > > case OVERLOAD: > > case TEMPLATE_ID_EXPR: > > case LABEL_DECL: > > -case LABEL_EXPR: > > case CASE_LABEL_EXPR: > > case PREDICT_EXPR: > > case CONST_DECL: > > @@ -8393,6 +8392,14 @@ potential_constant_expression_1 (tree t, bool > > want_rval, bool strict, bool now, > > return false; > > } > > +case LABEL_EXPR: > > + t = LABEL_EXPR_LABEL (t); > > + if (DECL_ARTIFICIAL (t) && DECL_IGNORED_P (t)) > > Is it useful to check DECL_IGNORED_P? I'd think we want to allow any > artificial labels, regardless of whether we're emitting debug info for them. Not really; I only checked it because create_artificial_label sets it. I'll commit the patch without that check. > OK either way. Thanks, Marek
Re: [PATCH] c++: Reject identifier label in constexpr [PR97846]
On 11/16/20 9:58 PM, Marek Polacek wrote: [dcl.constexpr]/3 says that the function-body of a constexpr function shall not contain an identifier label, but we aren't enforcing that. This patch implements that. Of course, we can't reject artificial labels. Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? gcc/cp/ChangeLog: PR c++/97846 * constexpr.c (potential_constant_expression_1): Reject LABEL_EXPRs that use non-artifical LABEL_DECLs. gcc/testsuite/ChangeLog: PR c++/97846 * g++.dg/cpp1y/constexpr-label.C: New test. --- gcc/cp/constexpr.c | 9 - gcc/testsuite/g++.dg/cpp1y/constexpr-label.C | 9 + 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-label.C diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index e6ab5eecd68..e4fbce14065 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -7484,7 +7484,6 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, case OVERLOAD: case TEMPLATE_ID_EXPR: case LABEL_DECL: -case LABEL_EXPR: case CASE_LABEL_EXPR: case PREDICT_EXPR: case CONST_DECL: @@ -8393,6 +8392,14 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, return false; } +case LABEL_EXPR: + t = LABEL_EXPR_LABEL (t); + if (DECL_ARTIFICIAL (t) && DECL_IGNORED_P (t)) Is it useful to check DECL_IGNORED_P? I'd think we want to allow any artificial labels, regardless of whether we're emitting debug info for them. OK either way. + return true; + else if (flags & tf_error) + error_at (loc, "label definition is not a constant expression"); + return false; + case ANNOTATE_EXPR: return RECUR (TREE_OPERAND (t, 0), rval); diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-label.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-label.C new file mode 100644 index 000..a2d113c186f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-label.C @@ -0,0 +1,9 @@ +// PR c++/97846 +// { dg-do compile { target c++14 } } + +constexpr int +f () +{ +x: // { dg-error "label definition is not a constant expression" } + return 42; +} base-commit: 814e016318646d06b1662219cc716d502b76d8ce
[PATCH] c++: Reject identifier label in constexpr [PR97846]
[dcl.constexpr]/3 says that the function-body of a constexpr function shall not contain an identifier label, but we aren't enforcing that. This patch implements that. Of course, we can't reject artificial labels. Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? gcc/cp/ChangeLog: PR c++/97846 * constexpr.c (potential_constant_expression_1): Reject LABEL_EXPRs that use non-artifical LABEL_DECLs. gcc/testsuite/ChangeLog: PR c++/97846 * g++.dg/cpp1y/constexpr-label.C: New test. --- gcc/cp/constexpr.c | 9 - gcc/testsuite/g++.dg/cpp1y/constexpr-label.C | 9 + 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-label.C diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index e6ab5eecd68..e4fbce14065 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -7484,7 +7484,6 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, case OVERLOAD: case TEMPLATE_ID_EXPR: case LABEL_DECL: -case LABEL_EXPR: case CASE_LABEL_EXPR: case PREDICT_EXPR: case CONST_DECL: @@ -8393,6 +8392,14 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, return false; } +case LABEL_EXPR: + t = LABEL_EXPR_LABEL (t); + if (DECL_ARTIFICIAL (t) && DECL_IGNORED_P (t)) + return true; + else if (flags & tf_error) + error_at (loc, "label definition is not a constant expression"); + return false; + case ANNOTATE_EXPR: return RECUR (TREE_OPERAND (t, 0), rval); diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-label.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-label.C new file mode 100644 index 000..a2d113c186f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-label.C @@ -0,0 +1,9 @@ +// PR c++/97846 +// { dg-do compile { target c++14 } } + +constexpr int +f () +{ +x: // { dg-error "label definition is not a constant expression" } + return 42; +} base-commit: 814e016318646d06b1662219cc716d502b76d8ce -- 2.28.0