]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR sanitizer/70135 (-fsanitize=undefined causes static_assert to fail)
authorJakub Jelinek <jakub@redhat.com>
Tue, 8 Mar 2016 20:05:21 +0000 (21:05 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 8 Mar 2016 20:05:21 +0000 (21:05 +0100)
PR c++/70135
* constexpr.c (cxx_eval_loop_expr): Forget saved values of SAVE_EXPRs
even after the last iteration of the loop.

* g++.dg/cpp1y/constexpr-loop4.C: New test.
* g++.dg/ubsan/pr70135.C: New test.

From-SVN: r234064

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

index 54dd3ecbc8e61be30f663165d8c5f2fdfbb3fece..5906ceb9e3b124a1cdfa22287a7f6a83631cfee8 100644 (file)
@@ -1,5 +1,9 @@
 2016-03-08  Jakub Jelinek  <jakub@redhat.com>
 
+       PR c++/70135
+       * constexpr.c (cxx_eval_loop_expr): Forget saved values of SAVE_EXPRs
+       even after the last iteration of the loop.
+
        * decl.c (duplicate_decls): Fix spelling - becuase -> because.
 
 2016-03-07  Patrick Palka  <ppalka@gcc.gnu.org>
index f23e7c91755f0b0fe630d5db9039871dd4e0b69b..7f3edcf431e9721aecba2cb2c4c79cee44032e95 100644 (file)
@@ -3165,21 +3165,21 @@ cxx_eval_loop_expr (const constexpr_ctx *ctx, tree t,
   constexpr_ctx new_ctx = *ctx;
 
   tree body = TREE_OPERAND (t, 0);
-  while (true)
+  do
     {
       hash_set<tree> save_exprs;
       new_ctx.save_exprs = &save_exprs;
 
       cxx_eval_statement_list (&new_ctx, body,
                               non_constant_p, overflow_p, jump_target);
-      if (returns (jump_target) || breaks (jump_target) || *non_constant_p)
-       break;
 
       /* Forget saved values of SAVE_EXPRs.  */
       for (hash_set<tree>::iterator iter = save_exprs.begin();
           iter != save_exprs.end(); ++iter)
        new_ctx.values->remove (*iter);
     }
+  while (!returns (jump_target) && !breaks (jump_target) && !*non_constant_p);
+
   if (breaks (jump_target))
     *jump_target = NULL_TREE;
 
index 28229ee4cf84d1b32cc11ed5a3949961b41d0a48..51494140033f89a53229a564dea75d5256fd26a9 100644 (file)
@@ -1,5 +1,9 @@
 2016-03-08  Jakub Jelinek  <jakub@redhat.com>
 
+       PR c++/70135
+       * g++.dg/cpp1y/constexpr-loop4.C: New test.
+       * g++.dg/ubsan/pr70135.C: New test.
+
        PR target/70110
        * gcc.dg/pr70110.c: New test.
 
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-loop4.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-loop4.C
new file mode 100644 (file)
index 0000000..67f7cfa
--- /dev/null
@@ -0,0 +1,27 @@
+// { dg-do compile { target c++14 } }
+
+struct A
+{
+  int i;
+};
+
+constexpr bool f()
+{
+  A ar[5] = { 6, 7, 8, 9, 10 };
+  A *ap = ar;
+  int i = 0, j = 0;
+  for (j = 0; j < 2; j++)
+    {
+      do
+       *ap++ = A{i};
+      while (++i < j * 2 + 2);
+    }
+  return (ar[0].i == 0
+         && ar[1].i == 1
+         && ar[2].i == 2
+         && ar[3].i == 3
+         && ar[4].i == 10);
+}
+
+#define SA(X) static_assert((X),#X)
+SA(f());
diff --git a/gcc/testsuite/g++.dg/ubsan/pr70135.C b/gcc/testsuite/g++.dg/ubsan/pr70135.C
new file mode 100644 (file)
index 0000000..340334a
--- /dev/null
@@ -0,0 +1,36 @@
+// PR c++/70135
+// { dg-do run }
+// { dg-options "-fsanitize=bounds -std=c++14" }
+
+template <bool... b>
+struct S {
+  static constexpr bool c[] {b...};
+  static constexpr auto foo ()
+  {
+    unsigned long n = 0;
+    for (unsigned long i = 0; i < sizeof (c); i++)
+      if (!c[i])
+       ++n;
+    return n;
+  }
+  static constexpr auto n = foo () + 1;
+  static constexpr auto bar ()
+  {
+    int h = 0;
+    for (int g = 0, i = 0; g < n; ++g)
+      {
+       while (i < sizeof...(b) && c[i++])
+         ++h;
+       h += 64;
+      }
+    return h;
+  }
+};
+
+int
+main ()
+{
+  S <true, false, false, true, true, true, false, true> s;
+  constexpr auto c = s.bar ();
+  static_assert (s.bar () == 4 * 64 + 5);
+}