This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Diagnose constexpr store to ARRAY_REF with negative index (PR c++/79655)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Jason Merrill <jason at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Tue, 21 Feb 2017 17:42:26 +0100
- Subject: [C++ PATCH] Diagnose constexpr store to ARRAY_REF with negative index (PR c++/79655)
- Authentication-results: sourceware.org; auth=none
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
The following patch fixes ICE where we try to store a[-1]. The problem
is that we don't check the bounds first and then later on we assert it
is not negative.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?
2017-02-21 Jakub Jelinek <jakub@redhat.com>
PR c++/79655
* constexpr.c (cxx_eval_array_reference): Diagnose negative subscript.
* g++.dg/cpp1y/constexpr-79655.C: New test.
--- gcc/cp/constexpr.c.jj 2017-02-17 18:29:21.000000000 +0100
+++ gcc/cp/constexpr.c 2017-02-21 13:49:06.530261975 +0100
@@ -2263,9 +2263,10 @@ cxx_eval_array_reference (const constexp
nelts = cxx_eval_constant_expression (ctx, nelts, false, non_constant_p,
overflow_p);
VERIFY_CONSTANT (nelts);
- if (lval
- ? !tree_int_cst_le (index, nelts)
- : !tree_int_cst_lt (index, nelts))
+ if ((lval
+ ? !tree_int_cst_le (index, nelts)
+ : !tree_int_cst_lt (index, nelts))
+ || tree_int_cst_sgn (index) < 0)
{
diag_array_subscript (ctx, ary, index);
*non_constant_p = true;
--- gcc/testsuite/g++.dg/cpp1y/constexpr-79655.C.jj 2017-02-21 14:14:37.245395108 +0100
+++ gcc/testsuite/g++.dg/cpp1y/constexpr-79655.C 2017-02-21 14:14:07.000000000 +0100
@@ -0,0 +1,18 @@
+// PR c++/79655
+// { dg-do compile { target c++14 } }
+
+constexpr int
+foo (int x, int y)
+{
+ int a[6] = { 1, 2, 3, 4, 5, 6 };
+ a[x] = 0;
+ return a[y];
+}
+
+constexpr int b = foo (0, -1); // { dg-error "is outside the bounds" }
+constexpr int c = foo (0, 6); // { dg-error "is outside the bounds" }
+constexpr int d = foo (6, 0); // { dg-error "is outside the bounds" }
+constexpr int e = foo (-1, 0); // { dg-error "is outside the bounds" }
+static_assert (foo (5, 5) == 0, "");
+static_assert (foo (4, 5) == 6, "");
+static_assert (foo (5, 4) == 5, "");
Jakub