re PR middle-end/66568 ([CHKP] internal compiler error: in expand_expr_addr_expr_1)

gcc/

	PR middle-end/66568
	* cfgexpand.c (expand_return): Handle missing bounds.
	(expand_gimple_stmt_1): Likewise.
	* tree-chkp.c (chkp_expand_zero_bounds): New.
	* tree-chkp.h (chkp_expand_zero_bounds): New.

gcc/testsuite/

	PR middle-end/66568
	* gcc.target/i386/mpx/pr66568.c: New test.

From-SVN: r224601
This commit is contained in:
Ilya Enkovich 2015-06-18 10:14:38 +00:00 committed by Ilya Enkovich
parent 847ffe1718
commit 855f036dcc
6 changed files with 95 additions and 34 deletions

View File

@ -1,3 +1,11 @@
2015-06-18 Ilya Enkovich <enkovich.gnu@gmail.com>
PR middle-end/66568
* cfgexpand.c (expand_return): Handle missing bounds.
(expand_gimple_stmt_1): Likewise.
* tree-chkp.c (chkp_expand_zero_bounds): New.
* tree-chkp.h (chkp_expand_zero_bounds): New.
2015-06-18 Ilya Enkovich <enkovich.gnu@gmail.com>
PR middle-end/66567

View File

@ -3134,18 +3134,25 @@ expand_return (tree retval, tree bounds)
bounds_rtl = DECL_BOUNDS_RTL (DECL_RESULT (current_function_decl));
if (bounds_rtl)
{
rtx addr, bnd;
rtx addr = NULL;
rtx bnd = NULL;
if (bounds)
if (bounds && bounds != error_mark_node)
{
bnd = expand_normal (bounds);
targetm.calls.store_returned_bounds (bounds_rtl, bnd);
}
else if (REG_P (bounds_rtl))
{
addr = expand_normal (build_fold_addr_expr (retval_rhs));
addr = gen_rtx_MEM (Pmode, addr);
bnd = targetm.calls.load_bounds_for_arg (addr, NULL, NULL);
if (bounds)
bnd = chkp_expand_zero_bounds ();
else
{
addr = expand_normal (build_fold_addr_expr (retval_rhs));
addr = gen_rtx_MEM (Pmode, addr);
bnd = targetm.calls.load_bounds_for_arg (addr, NULL, NULL);
}
targetm.calls.store_returned_bounds (bounds_rtl, bnd);
}
else
@ -3154,15 +3161,23 @@ expand_return (tree retval, tree bounds)
gcc_assert (GET_CODE (bounds_rtl) == PARALLEL);
addr = expand_normal (build_fold_addr_expr (retval_rhs));
addr = gen_rtx_MEM (Pmode, addr);
if (bounds)
bnd = chkp_expand_zero_bounds ();
else
{
addr = expand_normal (build_fold_addr_expr (retval_rhs));
addr = gen_rtx_MEM (Pmode, addr);
}
for (n = 0; n < XVECLEN (bounds_rtl, 0); n++)
{
rtx offs = XEXP (XVECEXP (bounds_rtl, 0, n), 1);
rtx slot = XEXP (XVECEXP (bounds_rtl, 0, n), 0);
rtx from = adjust_address (addr, Pmode, INTVAL (offs));
rtx bnd = targetm.calls.load_bounds_for_arg (from, NULL, NULL);
if (!bounds)
{
rtx offs = XEXP (XVECEXP (bounds_rtl, 0, n), 1);
rtx from = adjust_address (addr, Pmode, INTVAL (offs));
bnd = targetm.calls.load_bounds_for_arg (from, NULL, NULL);
}
targetm.calls.store_returned_bounds (slot, bnd);
}
}
@ -3259,33 +3274,40 @@ expand_gimple_stmt_1 (gimple stmt)
break;
case GIMPLE_RETURN:
op0 = gimple_return_retval (as_a <greturn *> (stmt));
{
tree bnd = gimple_return_retbnd (as_a <greturn *> (stmt));
op0 = gimple_return_retval (as_a <greturn *> (stmt));
if (op0 && op0 != error_mark_node)
{
tree result = DECL_RESULT (current_function_decl);
if (op0 && op0 != error_mark_node)
{
tree result = DECL_RESULT (current_function_decl);
/* If we are not returning the current function's RESULT_DECL,
build an assignment to it. */
if (op0 != result)
{
/* I believe that a function's RESULT_DECL is unique. */
gcc_assert (TREE_CODE (op0) != RESULT_DECL);
/* If we are not returning the current function's RESULT_DECL,
build an assignment to it. */
if (op0 != result)
{
/* I believe that a function's RESULT_DECL is unique. */
gcc_assert (TREE_CODE (op0) != RESULT_DECL);
/* ??? We'd like to use simply expand_assignment here,
but this fails if the value is of BLKmode but the return
decl is a register. expand_return has special handling
for this combination, which eventually should move
to common code. See comments there. Until then, let's
build a modify expression :-/ */
op0 = build2 (MODIFY_EXPR, TREE_TYPE (result),
result, op0);
}
}
if (!op0)
expand_null_return ();
else
expand_return (op0, gimple_return_retbnd (stmt));
/* ??? We'd like to use simply expand_assignment here,
but this fails if the value is of BLKmode but the return
decl is a register. expand_return has special handling
for this combination, which eventually should move
to common code. See comments there. Until then, let's
build a modify expression :-/ */
op0 = build2 (MODIFY_EXPR, TREE_TYPE (result),
result, op0);
}
/* Mark we have return statement with missing bounds. */
if (!bnd && chkp_function_instrumented_p (cfun->decl))
bnd = error_mark_node;
}
if (!op0)
expand_null_return ();
else
expand_return (op0, bnd);
}
break;
case GIMPLE_ASSIGN:

View File

@ -1,3 +1,8 @@
2015-06-18 Ilya Enkovich <enkovich.gnu@gmail.com>
PR middle-end/66568
* gcc.target/i386/mpx/pr66568.c: New test.
2015-06-18 Ilya Enkovich <enkovich.gnu@gmail.com>
PR middle-end/66567

View File

@ -0,0 +1,10 @@
/* { dg-do compile } */
/* { dg-require-effective-target fpic } */
/* { dg-options "-O2 -fcheck-pointer-bounds -mmpx -O2 -fPIC" } */
int a, b, c;
void *set_test () {
if (b)
a ? exit (0) : exit (1);
b = c;
}

View File

@ -466,6 +466,21 @@ chkp_gimple_call_builtin_p (gimple call,
return false;
}
/* Emit code to build zero bounds and return RTL holding
the result. */
rtx
chkp_expand_zero_bounds ()
{
tree zero_bnd;
if (flag_chkp_use_static_const_bounds)
zero_bnd = chkp_get_zero_bounds_var ();
else
zero_bnd = chkp_build_make_bounds_call (integer_zero_node,
integer_zero_node);
return expand_normal (zero_bnd);
}
/* Emit code to store zero bounds for PTR located at MEM. */
void
chkp_expand_bounds_reset_for_mem (tree mem, tree ptr)

View File

@ -53,6 +53,7 @@ extern void chkp_copy_bounds_for_assign (gimple assign,
struct cgraph_edge *edge);
extern bool chkp_gimple_call_builtin_p (gimple call,
enum built_in_function code);
extern rtx chkp_expand_zero_bounds (void);
extern void chkp_expand_bounds_reset_for_mem (tree mem, tree ptr);
extern tree chkp_insert_retbnd_call (tree bndval, tree retval,
gimple_stmt_iterator *gsi);