From 855f036dcc09c3c0a7718bdcb0fd4125b57c1dce Mon Sep 17 00:00:00 2001 From: Ilya Enkovich Date: Thu, 18 Jun 2015 10:14:38 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 8 ++ gcc/cfgexpand.c | 92 +++++++++++++-------- gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.target/i386/mpx/pr66568.c | 10 +++ gcc/tree-chkp.c | 15 ++++ gcc/tree-chkp.h | 1 + 6 files changed, 96 insertions(+), 35 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/mpx/pr66568.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 335ec7dbddc..23301d4beee 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2015-06-18 Ilya Enkovich + + 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 PR middle-end/66567 diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 06755d5491c..6b79b1dae77 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -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 (stmt)); + { + tree bnd = gimple_return_retbnd (as_a (stmt)); + op0 = gimple_return_retval (as_a (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); - - /* ??? 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)); + /* 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); + } + /* 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: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 95107ae6681..3b1d0710c1a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-06-18 Ilya Enkovich + + PR middle-end/66568 + * gcc.target/i386/mpx/pr66568.c: New test. + 2015-06-18 Ilya Enkovich PR middle-end/66567 diff --git a/gcc/testsuite/gcc.target/i386/mpx/pr66568.c b/gcc/testsuite/gcc.target/i386/mpx/pr66568.c new file mode 100644 index 00000000000..d7bb9f6e31d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/mpx/pr66568.c @@ -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; +} diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c index ed734e649c4..7ffec7b6305 100644 --- a/gcc/tree-chkp.c +++ b/gcc/tree-chkp.c @@ -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) diff --git a/gcc/tree-chkp.h b/gcc/tree-chkp.h index b5ab56252ed..6e41086ebe4 100644 --- a/gcc/tree-chkp.h +++ b/gcc/tree-chkp.h @@ -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); -- 2.30.2