PR c++/68206 - Fix constexpr diagnostics with loops.
authorJason Merrill <jason@redhat.com>
Tue, 19 Apr 2016 18:49:54 +0000 (14:49 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 19 Apr 2016 18:49:54 +0000 (14:49 -0400)
PR c++/68530
* constexpr.c (potential_constant_expression_1): Handle LOOP_EXPR
and GOTO_EXPR.

From-SVN: r235217

gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/testsuite/g++.dg/cpp1y/constexpr-loop5.C [new file with mode: 0644]

index 344cad023f77ea39d88125eab3a7cd11476cb5fd..5fb1654319299919233d5c24e370b6599235ee81 100644 (file)
@@ -1,5 +1,10 @@
 2016-04-19  Jason Merrill  <jason@redhat.com>
 
+       PR c++/68206
+       PR c++/68530
+       * constexpr.c (potential_constant_expression_1): Handle LOOP_EXPR
+       and GOTO_EXPR.
+
        * pt.c (tsubst_expr): Remove shadowing declaration.
        (tsubst_pack_expansion): Add assert.
 
index ae0c9739d8d6c1ebc504cdb04d0665d2c5a701cf..d50866094d1032a09b29a39f752552022682ba6a 100644 (file)
@@ -4924,6 +4924,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
     case NON_DEPENDENT_EXPR:
       /* For convenience.  */
     case RETURN_EXPR:
+    case LOOP_EXPR:
+    case EXIT_EXPR:
       return RECUR (TREE_OPERAND (t, 0), want_rval);
 
     case TRY_FINALLY_EXPR:
@@ -5135,6 +5137,15 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
     case EMPTY_CLASS_EXPR:
       return false;
 
+    case GOTO_EXPR:
+      {
+       tree *target = &TREE_OPERAND (t, 0);
+       /* Gotos representing break and continue are OK; we should have
+          rejected other gotos in parsing.  */
+       gcc_assert (breaks (target) || continues (target));
+       return true;
+      }
+
     default:
       if (objc_is_property_ref (t))
        return false;
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-loop5.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-loop5.C
new file mode 100644 (file)
index 0000000..02f372d
--- /dev/null
@@ -0,0 +1,19 @@
+// PR c++/68530
+// { dg-do compile { target c++14 } }
+
+struct thing {
+    void foo() {}
+};
+
+template<typename>
+constexpr int count()
+{
+    auto item = thing {};
+    for(; (item.foo(), false);); // { dg-error "foo" }
+    return 0;
+}
+
+int main()
+{
+    static_assert( count<int>() == 0, "" ); // { dg-error "" }
+}