aboutsummaryrefslogtreecommitdiff
path: root/gcc/cfgexpand.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cfgexpand.c')
-rw-r--r--gcc/cfgexpand.c61
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))
{