diff options
Diffstat (limited to 'gcc/cfgexpand.c')
-rw-r--r-- | gcc/cfgexpand.c | 61 |
1 files changed, 59 insertions, 2 deletions
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index d338a7c..2df8ce3 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -90,6 +90,8 @@ along with GCC; see the file COPYING3. If not see #include "recog.h" #include "output.h" #include "builtins.h" +#include "tree-chkp.h" +#include "rtl-chkp.h" /* Some systems use __main in a way incompatible with its use in gcc, in these cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to @@ -2316,6 +2318,7 @@ expand_call_stmt (gimple stmt) CALL_FROM_THUNK_P (exp) = gimple_call_from_thunk_p (stmt); CALL_EXPR_VA_ARG_PACK (exp) = gimple_call_va_arg_pack_p (stmt); SET_EXPR_LOCATION (exp, gimple_location (stmt)); + CALL_WITH_BOUNDS_P (exp) = gimple_call_with_bounds_p (stmt); /* Ensure RTL is created for debug args. */ if (decl && DECL_HAS_DEBUG_ARGS_P (decl)) @@ -3126,11 +3129,12 @@ expand_value_return (rtx val) from the current function. */ static void -expand_return (tree retval) +expand_return (tree retval, tree bounds) { rtx result_rtl; rtx val = 0; tree retval_rhs; + rtx bounds_rtl; /* If function wants no value, give it none. */ if (TREE_CODE (TREE_TYPE (TREE_TYPE (current_function_decl))) == VOID_TYPE) @@ -3156,6 +3160,56 @@ expand_return (tree retval) result_rtl = DECL_RTL (DECL_RESULT (current_function_decl)); + /* Put returned bounds to the right place. */ + bounds_rtl = DECL_BOUNDS_RTL (DECL_RESULT (current_function_decl)); + if (bounds_rtl) + { + rtx addr, bnd; + + if (bounds) + { + 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); + targetm.calls.store_returned_bounds (bounds_rtl, bnd); + } + else + { + int n; + + gcc_assert (GET_CODE (bounds_rtl) == PARALLEL); + + 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); + targetm.calls.store_returned_bounds (slot, bnd); + } + } + } + else if (chkp_function_instrumented_p (current_function_decl) + && !BOUNDED_P (retval_rhs) + && chkp_type_has_pointer (TREE_TYPE (retval_rhs)) + && TREE_CODE (retval_rhs) != RESULT_DECL) + { + rtx addr = expand_normal (build_fold_addr_expr (retval_rhs)); + addr = gen_rtx_MEM (Pmode, addr); + + gcc_assert (MEM_P (result_rtl)); + + chkp_copy_bounds_for_stack_parm (result_rtl, addr, TREE_TYPE (retval_rhs)); + } + /* If we are returning the RESULT_DECL, then the value has already been stored into it, so we don't have to do anything special. */ if (TREE_CODE (retval_rhs) == RESULT_DECL) @@ -3261,7 +3315,7 @@ expand_gimple_stmt_1 (gimple stmt) if (!op0) expand_null_return (); else - expand_return (op0); + expand_return (op0, gimple_return_retbnd (stmt)); break; case GIMPLE_ASSIGN: @@ -5654,6 +5708,9 @@ pass_expand::execute (function *fun) rtl_profile_for_bb (ENTRY_BLOCK_PTR_FOR_FN (fun)); + if (chkp_function_instrumented_p (current_function_decl)) + chkp_reset_rtl_bounds (); + insn_locations_init (); if (!DECL_IS_BUILTIN (current_function_decl)) { |