re PR c++/69509 (infinite loop compiling a VLA in a recursive constexpr function)
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. From-SVN: r232969
This commit is contained in:
parent
452ec2a5ec
commit
5453bfed48
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
21
gcc/testsuite/g++.dg/ext/constexpr-vla2.C
Normal file
21
gcc/testsuite/g++.dg/ext/constexpr-vla2.C
Normal file
@ -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" }
|
14
gcc/testsuite/g++.dg/ext/constexpr-vla3.C
Normal file
14
gcc/testsuite/g++.dg/ext/constexpr-vla3.C
Normal file
@ -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" }
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user