From: Jakub Jelinek Date: Tue, 8 Mar 2016 20:05:21 +0000 (+0100) Subject: re PR sanitizer/70135 (-fsanitize=undefined causes static_assert to fail) X-Git-Tag: basepoints/gcc-7~525 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d259b234a301aa5c06ca78262ae814b3d8d0f1a5;p=thirdparty%2Fgcc.git re PR sanitizer/70135 (-fsanitize=undefined causes static_assert to fail) 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 54dd3ecbc8e6..5906ceb9e3b1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2016-03-08 Jakub Jelinek + 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 diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index f23e7c91755f..7f3edcf431e9 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -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 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::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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 28229ee4cf84..51494140033f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2016-03-08 Jakub Jelinek + 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 index 000000000000..67f7cfa1d1d6 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-loop4.C @@ -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 index 000000000000..340334a15e4a --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/pr70135.C @@ -0,0 +1,36 @@ +// PR c++/70135 +// { dg-do run } +// { dg-options "-fsanitize=bounds -std=c++14" } + +template +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 s; + constexpr auto c = s.bar (); + static_assert (s.bar () == 4 * 64 + 5); +}