diff options
author | Ilya Enkovich <enkovich.gnu@gmail.com> | 2015-06-18 10:14:38 +0000 |
---|---|---|
committer | Ilya Enkovich <ienkovich@gcc.gnu.org> | 2015-06-18 10:14:38 +0000 |
commit | 855f036dcc09c3c0a7718bdcb0fd4125b57c1dce (patch) | |
tree | 555dbafe475f14c973a8d7cf45e60c09bd75dc1f /gcc/cfgexpand.c | |
parent | 847ffe1718d3eac1a1e605686e8bb27b25969ef0 (diff) | |
download | gcc-855f036dcc09c3c0a7718bdcb0fd4125b57c1dce.zip gcc-855f036dcc09c3c0a7718bdcb0fd4125b57c1dce.tar.gz gcc-855f036dcc09c3c0a7718bdcb0fd4125b57c1dce.tar.bz2 |
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
Diffstat (limited to 'gcc/cfgexpand.c')
-rw-r--r-- | gcc/cfgexpand.c | 92 |
1 files changed, 57 insertions, 35 deletions
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 06755d5..6b79b1d 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 <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); - - /* ??? 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: |