d: Move generation of array bounds error to own function.

gcc/d/ChangeLog:

	* d-codegen.cc (build_array_bounds_call): New function.
	(build_bounds_condition): Use build_array_bounds_call.
	* d-lang.cc (d_init_options): Explicitly set default check action to
	CHECKACTION_D.
	(d_post_options): Set check action to CHECKACTION_C if the flag
	-fno-druntime was seen.
	* d-tree.h (build_array_bounds_call): Declare.
	* expr.cc (ExprVisitor::visit (AssertExp *)): Use
	build_array_bounds_call.
This commit is contained in:
Iain Buclaw 2020-06-16 10:11:07 +02:00
parent e40b11a91c
commit f267a31098
4 changed files with 25 additions and 7 deletions

View file

@ -1712,6 +1712,26 @@ void_okay_p (tree t)
return t;
}
/* Builds a CALL_EXPR at location LOC in the source file to execute when an
array bounds check fails. */
tree
build_array_bounds_call (const Loc &loc)
{
switch (global.params.checkAction)
{
case CHECKACTION_D:
return d_assert_call (loc, LIBCALL_ARRAY_BOUNDS);
case CHECKACTION_C:
case CHECKACTION_halt:
return build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0);
default:
gcc_unreachable ();
}
}
/* Builds a bounds condition checking that INDEX is between 0 and LEN.
The condition returns the INDEX if true, or throws a RangeError.
If INCLUSIVE, we allow INDEX == LEN to return true also. */
@ -1731,9 +1751,7 @@ build_bounds_condition (const Loc& loc, tree index, tree len, bool inclusive)
tree condition = fold_build2 (inclusive ? GT_EXPR : GE_EXPR,
d_bool_type, index, len);
/* Terminate the program with a trap if no D runtime present. */
tree boundserr = (global.params.checkAction == CHECKACTION_D)
? d_assert_call (loc, LIBCALL_ARRAY_BOUNDS)
: build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0);
tree boundserr = build_array_bounds_call (loc);
return build_condition (TREE_TYPE (index), condition, boundserr, index);
}

View file

@ -285,6 +285,7 @@ d_init_options (unsigned int, cl_decoded_option *decoded_options)
global.params.useOut = CHECKENABLEdefault;
global.params.useArrayBounds = CHECKENABLEdefault;
global.params.useSwitchError = CHECKENABLEdefault;
global.params.checkAction = CHECKACTION_D;
global.params.useModuleInfo = true;
global.params.useTypeInfo = true;
global.params.useExceptions = true;
@ -775,7 +776,7 @@ d_post_options (const char ** fn)
if (!global_options_set.x_flag_exceptions)
global.params.useExceptions = false;
global.params.checkAction = CHECKACTION_halt;
global.params.checkAction = CHECKACTION_C;
}
/* Keep in sync with existing -fbounds-check flag. */

View file

@ -560,6 +560,7 @@ extern tree build_memref (tree, tree, tree);
extern tree build_array_set (tree, tree, tree);
extern tree build_array_from_val (Type *, tree);
extern tree void_okay_p (tree);
extern tree build_array_bounds_call (const Loc &);
extern tree build_bounds_condition (const Loc &, tree, tree, bool);
extern bool array_bounds_check (void);
extern tree bind_expr (tree, tree);

View file

@ -1218,9 +1218,7 @@ public:
if (!e->indexIsInBounds && array_bounds_check ())
{
tree tassert = (global.params.checkAction == CHECKACTION_D)
? d_assert_call (e->loc, LIBCALL_ARRAY_BOUNDS)
: build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0);
tree tassert = build_array_bounds_call (e->loc);
result = d_save_expr (result);
result = build_condition (TREE_TYPE (result),