summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormpolacek <mpolacek@138bc75d-0d04-0410-961f-82ee72b054a4>2016-01-29 09:25:14 +0000
committermpolacek <mpolacek@138bc75d-0d04-0410-961f-82ee72b054a4>2016-01-29 09:25:14 +0000
commitce6a6978e7b983220c7f95348e9c8585166f43c2 (patch)
treeeafb02c3b10525280e4825fa8103c05dc0a2a8a9
parent7550d8552dd015e7bfa1eb5d0e5bbff9db431262 (diff)
downloadgcc-ce6a6978e7b983220c7f95348e9c8585166f43c2.tar.gz
PR c++/69509
PR c++/69516 * constexpr.c (cxx_eval_array_reference): Give the "array subscript out of bound" error earlier. * init.c (build_vec_init): Change NE_EXPR into GT_EXPR. Update the commentary. * g++.dg/ext/constexpr-vla2.C: New test. * g++.dg/ext/constexpr-vla3.C: New test. * g++.dg/ubsan/vla-1.C: Remove dg-shouldfail. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@232969 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/constexpr.c55
-rw-r--r--gcc/cp/init.c4
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/g++.dg/ext/constexpr-vla2.C21
-rw-r--r--gcc/testsuite/g++.dg/ext/constexpr-vla3.C14
-rw-r--r--gcc/testsuite/g++.dg/ubsan/vla-1.C1
7 files changed, 81 insertions, 31 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 2c2cdfb0d0c..6c66cc4747a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+2016-01-29 Marek Polacek <polacek@redhat.com>
+
+ PR c++/69509
+ PR c++/69516
+ * constexpr.c (cxx_eval_array_reference): Give the "array subscript
+ out of bound" error earlier.
+ * init.c (build_vec_init): Change NE_EXPR into GT_EXPR. Update the
+ commentary.
+
2016-01-29 Patrick Palka <ppalka@gcc.gnu.org>
* name-lookup.c (begin_scope): After reusing a cp_binding_level
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 57595a40026..b0769914d45 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -1833,6 +1833,19 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
return t;
}
+ tree nelts = array_type_nelts_top (TREE_TYPE (ary));
+ /* For VLAs, the number of elements won't be an integer constant. */
+ nelts = cxx_eval_constant_expression (ctx, nelts, false, non_constant_p,
+ overflow_p);
+ VERIFY_CONSTANT (nelts);
+ if (!tree_int_cst_lt (index, nelts))
+ {
+ if (!ctx->quiet)
+ error ("array subscript out of bound");
+ *non_constant_p = true;
+ return t;
+ }
+
bool found;
if (TREE_CODE (ary) == CONSTRUCTOR)
{
@@ -1846,37 +1859,23 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
if (!found)
{
- tree nelts = array_type_nelts_top (TREE_TYPE (ary));
- /* For VLAs, the number of elements won't be an integer constant. */
- nelts = cxx_eval_constant_expression (ctx, nelts, false, non_constant_p,
- overflow_p);
- VERIFY_CONSTANT (nelts);
- if (tree_int_cst_lt (index, nelts))
+ if (TREE_CODE (ary) == CONSTRUCTOR
+ && CONSTRUCTOR_NO_IMPLICIT_ZERO (ary))
{
- if (TREE_CODE (ary) == CONSTRUCTOR
- && CONSTRUCTOR_NO_IMPLICIT_ZERO (ary))
- {
- /* 'ary' is part of the aggregate initializer we're currently
- building; if there's no initializer for this element yet,
- that's an error. */
- if (!ctx->quiet)
- error ("accessing uninitialized array element");
- *non_constant_p = true;
- return t;
- }
-
- /* If it's within the array bounds but doesn't have an explicit
- initializer, it's value-initialized. */
- tree val = build_value_init (elem_type, tf_warning_or_error);
- return cxx_eval_constant_expression (ctx, val,
- lval,
- non_constant_p, overflow_p);
+ /* 'ary' is part of the aggregate initializer we're currently
+ building; if there's no initializer for this element yet,
+ that's an error. */
+ if (!ctx->quiet)
+ error ("accessing uninitialized array element");
+ *non_constant_p = true;
+ return t;
}
- if (!ctx->quiet)
- error ("array subscript out of bound");
- *non_constant_p = true;
- return t;
+ /* If it's within the array bounds but doesn't have an explicit
+ initializer, it's value-initialized. */
+ tree val = build_value_init (elem_type, tf_warning_or_error);
+ return cxx_eval_constant_expression (ctx, val, lval, non_constant_p,
+ overflow_p);
}
if (TREE_CODE (ary) == CONSTRUCTOR)
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 9f7b614a293..976ada84587 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -4008,7 +4008,7 @@ build_vec_init (tree base, tree maxindex, tree init,
&& (num_initialized_elts
== tree_to_shwi (maxindex) + 1))))
{
- /* If the ITERATOR is equal to -1, then we don't have to loop;
+ /* If the ITERATOR is lesser or equal to -1, then we don't have to loop;
we've already initialized all the elements. */
tree for_stmt;
tree elt_init;
@@ -4016,7 +4016,7 @@ build_vec_init (tree base, tree maxindex, tree init,
for_stmt = begin_for_stmt (NULL_TREE, NULL_TREE);
finish_for_init_stmt (for_stmt);
- finish_for_cond (build2 (NE_EXPR, boolean_type_node, iterator,
+ finish_for_cond (build2 (GT_EXPR, boolean_type_node, iterator,
build_int_cst (TREE_TYPE (iterator), -1)),
for_stmt, false);
elt_init = cp_build_unary_op (PREDECREMENT_EXPR, iterator, 0,
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3c271847f7c..c20ea73f52f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2016-01-29 Marek Polacek <polacek@redhat.com>
+
+ PR c++/69509
+ PR c++/69516
+ * g++.dg/ext/constexpr-vla2.C: New test.
+ * g++.dg/ext/constexpr-vla3.C: New test.
+ * g++.dg/ubsan/vla-1.C: Remove dg-shouldfail.
+
2016-01-29 Richard Biener <rguenther@suse.de>
PR middle-end/69537
diff --git a/gcc/testsuite/g++.dg/ext/constexpr-vla2.C b/gcc/testsuite/g++.dg/ext/constexpr-vla2.C
new file mode 100644
index 00000000000..6cb1f708a23
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/constexpr-vla2.C
@@ -0,0 +1,21 @@
+// PR c++/69509
+// { dg-do compile { target c++14 } }
+
+constexpr int
+fn_bad (int n)
+{
+ __extension__ int a [n] = { 0 };
+ int z = a [0] + (n ? fn_bad (n - 1) : 0);
+ return z;
+}
+
+constexpr int
+fn_ok (int n)
+{
+ __extension__ int a [n] = { 0 };
+ int z = a [0] + (n > 1 ? fn_ok (n - 1) : 0);
+ return z;
+}
+
+constexpr int i1 = fn_ok (3);
+constexpr int i2 = fn_bad (3); // { dg-error "array subscript out of bound" }
diff --git a/gcc/testsuite/g++.dg/ext/constexpr-vla3.C b/gcc/testsuite/g++.dg/ext/constexpr-vla3.C
new file mode 100644
index 00000000000..ba4eb50f5de
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/constexpr-vla3.C
@@ -0,0 +1,14 @@
+// PR c++/69516
+// { dg-do compile { target c++14 } }
+
+constexpr int
+foo (int n)
+{
+ __extension__ int a[n] = { 1, 2, 3, 4, 5, 6 };
+ int z = 0;
+ for (int i = 0; i <= n; ++i)
+ z += a[i];
+ return z;
+}
+
+constexpr int n = foo (3); // { dg-error "array subscript out of bound" }
diff --git a/gcc/testsuite/g++.dg/ubsan/vla-1.C b/gcc/testsuite/g++.dg/ubsan/vla-1.C
index e7f24945f7a..311cdb1d77a 100644
--- a/gcc/testsuite/g++.dg/ubsan/vla-1.C
+++ b/gcc/testsuite/g++.dg/ubsan/vla-1.C
@@ -1,6 +1,5 @@
// { dg-do run }
// { dg-options "-Wno-vla -fsanitize=undefined" }
-// { dg-shouldfail "ubsan" }
// { dg-output "index 1 out of bounds" }
void f(int i) {