Commit 46621807 by Jason Merrill Committed by Jason Merrill

init.c (build_vec_init): Call ubsan_instrument_bounds to check whether an…

init.c (build_vec_init): Call ubsan_instrument_bounds to check whether an initializer-list is too big...

	* init.c (build_vec_init): Call ubsan_instrument_bounds to check
	whether an initializer-list is too big for a VLA.
	(throw_bad_array_length): Remove.
	* cp-tree.h: Remove prototype.

From-SVN: r219359
parent d9ebff44
2015-01-08 Jason Merrill <jason@redhat.com>
* init.c (build_vec_init): Call ubsan_instrument_bounds to check
whether an initializer-list is too big for a VLA.
(throw_bad_array_length): Remove.
* cp-tree.h: Remove prototype.
2015-01-08 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/60753
......
......@@ -5574,7 +5574,6 @@ extern tree get_nsdmi (tree, bool);
extern tree build_offset_ref (tree, tree, bool,
tsubst_flags_t);
extern tree throw_bad_array_new_length (void);
extern tree throw_bad_array_length (void);
extern tree build_new (vec<tree, va_gc> **, tree, tree,
vec<tree, va_gc> **, int,
tsubst_flags_t);
......
......@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see
#include "target.h"
#include "gimplify.h"
#include "wide-int.h"
#include "c-family/c-ubsan.h"
static bool begin_init_stmts (tree *, tree *);
static tree finish_init_stmts (bool, tree, tree);
......@@ -2241,20 +2242,6 @@ throw_bad_array_new_length (void)
return build_cxx_call (fn, 0, NULL, tf_warning_or_error);
}
/* Call __cxa_bad_array_length to indicate that there were too many
initializers. */
tree
throw_bad_array_length (void)
{
tree fn = get_identifier ("__cxa_throw_bad_array_length");
if (!get_global_value_if_present (fn, &fn))
fn = push_throw_library_fn (fn, build_function_type_list (void_type_node,
NULL_TREE));
return build_cxx_call (fn, 0, NULL, tf_warning_or_error);
}
/* Generate code for a new-expression, including calling the "operator
new" function, initializing the object, and, if an exception occurs
during construction, cleaning up. The arguments are as for
......@@ -3419,7 +3406,6 @@ build_vec_init (tree base, tree maxindex, tree init,
tree obase = base;
bool xvalue = false;
bool errors = false;
tree length_check = NULL_TREE;
if (TREE_CODE (atype) == ARRAY_TYPE && TYPE_DOMAIN (atype))
maxindex = array_type_nelts (atype);
......@@ -3440,12 +3426,9 @@ build_vec_init (tree base, tree maxindex, tree init,
/* If we have a braced-init-list, make sure that the array
is big enough for all the initializers. */
if (init && TREE_CODE (init) == CONSTRUCTOR
&& CONSTRUCTOR_NELTS (init) > 0
&& !TREE_CONSTANT (maxindex)
&& flag_exceptions)
length_check = fold_build2 (LT_EXPR, boolean_type_node, maxindex,
size_int (CONSTRUCTOR_NELTS (init) - 1));
bool length_check = (init && TREE_CODE (init) == CONSTRUCTOR
&& CONSTRUCTOR_NELTS (init) > 0
&& !TREE_CONSTANT (maxindex));
if (init
&& TREE_CODE (atype) == ARRAY_TYPE
......@@ -3468,10 +3451,6 @@ build_vec_init (tree base, tree maxindex, tree init,
if (BRACE_ENCLOSED_INITIALIZER_P (init))
init = digest_init (atype, init, complain);
stmt_expr = build2 (INIT_EXPR, atype, base, init);
if (length_check)
stmt_expr = build3 (COND_EXPR, atype, length_check,
throw_bad_array_length (),
stmt_expr);
return stmt_expr;
}
......@@ -3582,11 +3561,30 @@ build_vec_init (tree base, tree maxindex, tree init,
if (length_check)
{
tree throw_call;
throw_call = throw_bad_array_new_length ();
length_check = build3 (COND_EXPR, void_type_node, length_check,
throw_call, void_node);
finish_expr_stmt (length_check);
tree nelts = size_int (CONSTRUCTOR_NELTS (init) - 1);
if (TREE_CODE (atype) != ARRAY_TYPE)
{
if (flag_exceptions)
{
tree c = fold_build2 (LT_EXPR, boolean_type_node, iterator,
nelts);
c = build3 (COND_EXPR, void_type_node, c,
throw_bad_array_new_length (), void_node);
finish_expr_stmt (c);
}
/* Don't check an array new when -fno-exceptions. */
}
else if (flag_sanitize & SANITIZE_BOUNDS
&& current_function_decl
&& !lookup_attribute ("no_sanitize_undefined",
DECL_ATTRIBUTES
(current_function_decl)))
{
/* Make sure the last element of the initializer is in bounds. */
finish_expr_stmt
(ubsan_instrument_bounds
(input_location, obase, &nelts, /*ignore_off_by_one*/false));
}
}
if (try_const)
......
......@@ -5629,9 +5629,7 @@ call into a diagnostics message call instead. When reaching the
@item -fsanitize=vla-bound
@opindex fsanitize=vla-bound
This option instructs the compiler to check that the size of a variable
length array is positive. This option does not have any effect in
@option{-std=c++14} mode, as the standard requires the exception be thrown
instead.
length array is positive.
@item -fsanitize=null
@opindex fsanitize=null
......
// { dg-do run }
// { dg-options "-Wno-vla -fsanitize=undefined" }
// { dg-shouldfail "ubsan" }
// { dg-output "index 1 out of bounds" }
void f(int i) {
int ar[i] = { 42, 24 };
}
int main()
{
f(1);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment