aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2018-08-06 16:46:13 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2018-08-06 16:46:13 +0000
commit0250ba589bc7b294d3d1372372b79ea0c9c19817 (patch)
tree2f586cc6affa60ecebc930f003dfcec2b5584b69
parent5242b3cb24325fb1ff32a71383ae2e7f855b2c06 (diff)
downloadgcc-0250ba589bc7b294d3d1372372b79ea0c9c19817.zip
gcc-0250ba589bc7b294d3d1372372b79ea0c9c19817.tar.gz
gcc-0250ba589bc7b294d3d1372372b79ea0c9c19817.tar.bz2
re PR c++/86767 (continue statements in constexpr functions causes unbounded looping)
PR c++/86767 * constexpr.c (cxx_eval_statement_list): Handle continue. * g++.dg/cpp1y/constexpr-86767.C: New test. From-SVN: r263340
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/constexpr.c10
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-86767.C119
4 files changed, 139 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 90af73d..7cf87f8 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,8 @@
+2018-08-06 Marek Polacek <polacek@redhat.com>
+
+ PR c++/86767
+ * constexpr.c (cxx_eval_statement_list): Handle continue.
+
2018-08-03 David Malcolm <dmalcolm@redhat.com>
Jonathan Wakely <jwakely@redhat.com>
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 365296d..79039ff 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -3950,6 +3950,16 @@ cxx_eval_statement_list (const constexpr_ctx *ctx, tree t,
for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
{
tree stmt = tsi_stmt (i);
+ /* We've found a continue, so skip everything until we reach
+ the label its jumping to. */
+ if (continues (jump_target))
+ {
+ if (label_matches (ctx, jump_target, stmt))
+ /* Found it. */
+ *jump_target = NULL_TREE;
+ else
+ continue;
+ }
if (TREE_CODE (stmt) == DEBUG_BEGIN_STMT)
continue;
r = cxx_eval_constant_expression (ctx, stmt, false,
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 71e3ad7..eec7461 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2018-08-06 Marek Polacek <polacek@redhat.com>
+
+ PR c++/86767
+ * g++.dg/cpp1y/constexpr-86767.C: New test.
+
2018-08-06 Uros Bizjak <ubizjak@gmail.com>
* g++.dg/torture/pr86763.C (dg-additional-options): Add -lrt
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-86767.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-86767.C
new file mode 100644
index 0000000..2ad71d5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-86767.C
@@ -0,0 +1,119 @@
+// PR c++/86767
+// { dg-do compile { target c++14 } }
+
+constexpr int
+fn0 () noexcept
+{
+ int r = 0;
+ for (int i = 0; i < 10; ++i)
+ {
+ continue;
+ r++;
+ for (int j = 0; j < 10; ++j )
+ {
+ }
+ }
+ return r;
+}
+static_assert (fn0 () == 0, "");
+
+constexpr int
+fn1 () noexcept
+{
+ int r = 0;
+ for (int i = 0; i < 10; ++i)
+ for (int j = 0; j < 10; ++j)
+ {
+ continue;
+ r++;
+ }
+ return r;
+}
+static_assert (fn1 () == 0, "");
+
+constexpr int
+fn2 () noexcept
+{
+ int r = 0;
+ for (int i = 0; i < 10; ++i)
+ {
+ continue;
+ r++;
+ }
+ return r;
+}
+static_assert (fn2 () == 0, "");
+
+constexpr int
+fn3 () noexcept
+{
+ int r = 0;
+ for (int i = 0; i < 10; ++i)
+ {
+ continue;
+ r++;
+ while (1)
+ {
+ }
+ }
+ return r;
+}
+static_assert (fn3 () == 0, "");
+
+constexpr int
+fn4 () noexcept
+{
+ for (int i = 0; i < 10; ++i)
+ {
+ switch (i)
+ {
+ case 5:
+ return i;
+ default:
+ continue;
+ }
+ while (1)
+ {
+ }
+ }
+ return 0;
+}
+static_assert (fn4 () == 5, "");
+
+constexpr int
+fn5 () noexcept
+{
+ for (int i = 0; i < 10; ++i)
+ {
+ switch (i)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ continue;
+ default:
+ return i;
+ }
+ while (1)
+ {
+ }
+ }
+ return 0;
+}
+static_assert (fn5 () == 5, "");
+
+constexpr int
+fn6 () noexcept
+{
+ int r = 0;
+ for (int i = 0; i < 10; ++i)
+ {
+ continue;
+ for (int j = 0; j < 10; ++j )
+ r++;
+ }
+ return r;
+}
+static_assert (fn6 () == 0, "");