Message ID | 20201117025828.2092321-1-polacek@redhat.com |
---|---|
State | New |
Headers | show |
Series | c++: Reject identifier label in constexpr [PR97846] | expand |
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 00000000000..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 >
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
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 00000000000..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; +}