c++: Reject identifier label in constexpr [PR97846]
authorMarek Polacek <polacek@redhat.com>
Tue, 17 Nov 2020 00:59:35 +0000 (19:59 -0500)
committerMarek Polacek <polacek@redhat.com>
Sat, 21 Nov 2020 21:08:33 +0000 (16:08 -0500)
[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.

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
gcc/testsuite/g++.dg/cpp1y/constexpr-label.C [new file with mode: 0644]

index ef37b3043a54db4e0cfb5cf930ada76e1af2fc1c..4513d40cda54eb9ddd9620ff007a15bf4f2cdd4a 100644 (file)
@@ -7502,7 +7502,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:
@@ -8411,6 +8410,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))
+       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 (file)
index 0000000..a2d113c
--- /dev/null
@@ -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;
+}