PR c++/87594 - constexpr rejects-valid with range-based for.
authorMarek Polacek <polacek@redhat.com>
Mon, 29 Oct 2018 19:40:18 +0000 (19:40 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Mon, 29 Oct 2018 19:40:18 +0000 (19:40 +0000)
* constexpr.c (potential_constant_expression_1): If the condition
can't be evaluated, return true.

* g++.dg/cpp1y/constexpr-loop8.C: New test.

From-SVN: r265600

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

index 9130b8663d3fef771834110e0f35c87d36653216..6b9574a652730f500c6b496a3c524200eb21e4c5 100644 (file)
@@ -1,3 +1,9 @@
+2018-10-29  Marek Polacek  <polacek@redhat.com>
+
+       PR c++/87594 - constexpr rejects-valid with range-based for.
+       * constexpr.c (potential_constant_expression_1): If the condition
+       can't be evaluated, return true.
+
 2018-10-29  Joseph Myers  <joseph@codesourcery.com>
            Julian Brown  <julian@codesourcery.com>
 
index 4fa8c965a9d56a458077825072f005e2d5669bca..7692b1727da0219fa9f19db714bd4f0f6a114254 100644 (file)
@@ -5825,7 +5825,9 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
        {
          if (!processing_template_decl)
            tmp = cxx_eval_outermost_constant_expr (tmp, true);
-         if (integer_zerop (tmp))
+         /* If we couldn't evaluate the condition, it might not ever be
+            true.  */
+         if (!integer_onep (tmp))
            return true;
        }
       if (!RECUR (FOR_EXPR (t), any))
@@ -5853,7 +5855,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
        return false;
       if (!processing_template_decl)
        tmp = cxx_eval_outermost_constant_expr (tmp, true);
-      if (integer_zerop (tmp))
+      /* If we couldn't evaluate the condition, it might not ever be true.  */
+      if (!integer_onep (tmp))
        return true;
       if (!RECUR (WHILE_BODY (t), any))
        return false;
index 6cc3e1bb86a355ed51fcdc696db7ebce808cb4c0..bfccc6038cad0273ede1774a0e345d946bfa0b46 100644 (file)
@@ -1,3 +1,8 @@
+2018-10-29  Marek Polacek  <polacek@redhat.com>
+
+       PR c++/87594 - constexpr rejects-valid with range-based for.
+       * g++.dg/cpp1y/constexpr-loop8.C: New test.
+
 2018-10-29  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/87785
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-loop8.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-loop8.C
new file mode 100644 (file)
index 0000000..bf132f2
--- /dev/null
@@ -0,0 +1,44 @@
+// PR c++/87594
+// { dg-do compile { target c++14 } }
+
+constexpr bool always_false() { return false; }
+int f() { return 1; }
+
+constexpr int
+fn1()
+{
+  struct empty_range {
+    constexpr int* begin() { return 0; }
+    constexpr int* end() { return 0; }
+  } e;
+  for (auto x : e)
+    f();
+  return 0;
+}
+
+constexpr int
+fn2 ()
+{
+  int a[] = { 1, 2, 3 };
+  for (auto x : a)
+    f(); // { dg-error "call to non-.constexpr. function" }
+  return 0;
+}
+
+constexpr int
+fn3 ()
+{
+  __extension__ int a[] = { };
+  for (auto x : a)
+    f();
+  return 0;
+}
+
+
+void
+bar ()
+{
+  constexpr int i1 = fn1 ();
+  constexpr int i2 = fn2 (); // { dg-message "in .constexpr. expansion of " }
+  constexpr int i3 = fn3 ();
+}