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> 2015-01-08 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/60753 PR c++/60753
......
...@@ -5574,7 +5574,6 @@ extern tree get_nsdmi (tree, bool); ...@@ -5574,7 +5574,6 @@ extern tree get_nsdmi (tree, bool);
extern tree build_offset_ref (tree, tree, bool, extern tree build_offset_ref (tree, tree, bool,
tsubst_flags_t); tsubst_flags_t);
extern tree throw_bad_array_new_length (void); 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, extern tree build_new (vec<tree, va_gc> **, tree, tree,
vec<tree, va_gc> **, int, vec<tree, va_gc> **, int,
tsubst_flags_t); tsubst_flags_t);
......
...@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see
#include "target.h" #include "target.h"
#include "gimplify.h" #include "gimplify.h"
#include "wide-int.h" #include "wide-int.h"
#include "c-family/c-ubsan.h"
static bool begin_init_stmts (tree *, tree *); static bool begin_init_stmts (tree *, tree *);
static tree finish_init_stmts (bool, tree, tree); static tree finish_init_stmts (bool, tree, tree);
...@@ -2241,20 +2242,6 @@ throw_bad_array_new_length (void) ...@@ -2241,20 +2242,6 @@ throw_bad_array_new_length (void)
return build_cxx_call (fn, 0, NULL, tf_warning_or_error); 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 /* Generate code for a new-expression, including calling the "operator
new" function, initializing the object, and, if an exception occurs new" function, initializing the object, and, if an exception occurs
during construction, cleaning up. The arguments are as for during construction, cleaning up. The arguments are as for
...@@ -3419,7 +3406,6 @@ build_vec_init (tree base, tree maxindex, tree init, ...@@ -3419,7 +3406,6 @@ build_vec_init (tree base, tree maxindex, tree init,
tree obase = base; tree obase = base;
bool xvalue = false; bool xvalue = false;
bool errors = false; bool errors = false;
tree length_check = NULL_TREE;
if (TREE_CODE (atype) == ARRAY_TYPE && TYPE_DOMAIN (atype)) if (TREE_CODE (atype) == ARRAY_TYPE && TYPE_DOMAIN (atype))
maxindex = array_type_nelts (atype); maxindex = array_type_nelts (atype);
...@@ -3440,12 +3426,9 @@ build_vec_init (tree base, tree maxindex, tree init, ...@@ -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 /* If we have a braced-init-list, make sure that the array
is big enough for all the initializers. */ is big enough for all the initializers. */
if (init && TREE_CODE (init) == CONSTRUCTOR bool length_check = (init && TREE_CODE (init) == CONSTRUCTOR
&& CONSTRUCTOR_NELTS (init) > 0 && CONSTRUCTOR_NELTS (init) > 0
&& !TREE_CONSTANT (maxindex) && !TREE_CONSTANT (maxindex));
&& flag_exceptions)
length_check = fold_build2 (LT_EXPR, boolean_type_node, maxindex,
size_int (CONSTRUCTOR_NELTS (init) - 1));
if (init if (init
&& TREE_CODE (atype) == ARRAY_TYPE && TREE_CODE (atype) == ARRAY_TYPE
...@@ -3468,10 +3451,6 @@ build_vec_init (tree base, tree maxindex, tree init, ...@@ -3468,10 +3451,6 @@ build_vec_init (tree base, tree maxindex, tree init,
if (BRACE_ENCLOSED_INITIALIZER_P (init)) if (BRACE_ENCLOSED_INITIALIZER_P (init))
init = digest_init (atype, init, complain); init = digest_init (atype, init, complain);
stmt_expr = build2 (INIT_EXPR, atype, base, init); 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; return stmt_expr;
} }
...@@ -3582,11 +3561,30 @@ build_vec_init (tree base, tree maxindex, tree init, ...@@ -3582,11 +3561,30 @@ build_vec_init (tree base, tree maxindex, tree init,
if (length_check) if (length_check)
{ {
tree throw_call; tree nelts = size_int (CONSTRUCTOR_NELTS (init) - 1);
throw_call = throw_bad_array_new_length (); if (TREE_CODE (atype) != ARRAY_TYPE)
length_check = build3 (COND_EXPR, void_type_node, length_check, {
throw_call, void_node); if (flag_exceptions)
finish_expr_stmt (length_check); {
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) if (try_const)
......
...@@ -5629,9 +5629,7 @@ call into a diagnostics message call instead. When reaching the ...@@ -5629,9 +5629,7 @@ call into a diagnostics message call instead. When reaching the
@item -fsanitize=vla-bound @item -fsanitize=vla-bound
@opindex fsanitize=vla-bound @opindex fsanitize=vla-bound
This option instructs the compiler to check that the size of a variable 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 length array is positive.
@option{-std=c++14} mode, as the standard requires the exception be thrown
instead.
@item -fsanitize=null @item -fsanitize=null
@opindex 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