diff options
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 71 |
1 files changed, 62 insertions, 9 deletions
diff --git a/gcc/expr.c b/gcc/expr.c index f4047c418cd..f824cef3894 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -79,6 +79,8 @@ along with GCC; see the file COPYING3. If not see #include "tree-ssa-address.h" #include "cfgexpand.h" #include "builtins.h" +#include "tree-chkp.h" +#include "rtl-chkp.h" #ifndef STACK_PUSH_CODE #ifdef STACK_GROWS_DOWNWARD @@ -5006,9 +5008,14 @@ expand_assignment (tree to, tree from, bool nontemporal) || TREE_CODE (to) == SSA_NAME)) { rtx value; + rtx bounds; push_temp_slots (); value = expand_normal (from); + + /* Split value and bounds to store them separately. */ + chkp_split_slot (value, &value, &bounds); + if (to_rtx == 0) to_rtx = expand_expr (to, NULL_RTX, VOIDmode, EXPAND_WRITE); @@ -5042,6 +5049,15 @@ expand_assignment (tree to, tree from, bool nontemporal) emit_move_insn (to_rtx, value); } + + /* Store bounds if required. */ + if (bounds + && (BOUNDED_P (to) || chkp_type_has_pointer (TREE_TYPE (to)))) + { + gcc_assert (MEM_P (to_rtx)); + chkp_emit_bounds_store (bounds, value, to_rtx); + } + preserve_temp_slots (to_rtx); pop_temp_slots (); return; @@ -5117,7 +5133,7 @@ expand_assignment (tree to, tree from, bool nontemporal) /* Compute FROM and store the value in the rtx we got. */ push_temp_slots (); - result = store_expr (from, to_rtx, 0, nontemporal); + result = store_expr_with_bounds (from, to_rtx, 0, nontemporal, to); preserve_temp_slots (result); pop_temp_slots (); return; @@ -5154,10 +5170,14 @@ emit_storent_insn (rtx to, rtx from) If CALL_PARAM_P is nonzero, this is a store into a call param on the stack, and block moves may need to be treated specially. - If NONTEMPORAL is true, try using a nontemporal store instruction. */ + If NONTEMPORAL is true, try using a nontemporal store instruction. + + If BTARGET is not NULL then computed bounds of EXP are + associated with BTARGET. */ rtx -store_expr (tree exp, rtx target, int call_param_p, bool nontemporal) +store_expr_with_bounds (tree exp, rtx target, int call_param_p, + bool nontemporal, tree btarget) { rtx temp; rtx alt_rtl = NULL_RTX; @@ -5178,8 +5198,8 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal) part. */ expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, call_param_p ? EXPAND_STACK_PARM : EXPAND_NORMAL); - return store_expr (TREE_OPERAND (exp, 1), target, call_param_p, - nontemporal); + return store_expr_with_bounds (TREE_OPERAND (exp, 1), target, + call_param_p, nontemporal, btarget); } else if (TREE_CODE (exp) == COND_EXPR && GET_MODE (target) == BLKmode) { @@ -5193,13 +5213,13 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal) do_pending_stack_adjust (); NO_DEFER_POP; jumpifnot (TREE_OPERAND (exp, 0), lab1, -1); - store_expr (TREE_OPERAND (exp, 1), target, call_param_p, - nontemporal); + store_expr_with_bounds (TREE_OPERAND (exp, 1), target, call_param_p, + nontemporal, btarget); emit_jump_insn (gen_jump (lab2)); emit_barrier (); emit_label (lab1); - store_expr (TREE_OPERAND (exp, 2), target, call_param_p, - nontemporal); + store_expr_with_bounds (TREE_OPERAND (exp, 2), target, call_param_p, + nontemporal, btarget); emit_label (lab2); OK_DEFER_POP; @@ -5251,6 +5271,19 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal) temp = expand_expr (exp, inner_target, VOIDmode, call_param_p ? EXPAND_STACK_PARM : EXPAND_NORMAL); + /* Handle bounds returned by call. */ + if (TREE_CODE (exp) == CALL_EXPR) + { + rtx bounds; + chkp_split_slot (temp, &temp, &bounds); + if (bounds && btarget) + { + gcc_assert (TREE_CODE (btarget) == SSA_NAME); + rtx tmp = targetm.calls.load_returned_bounds (bounds); + chkp_set_rtl_bounds (btarget, tmp); + } + } + /* If TEMP is a VOIDmode constant, use convert_modes to make sure that we properly convert it. */ if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode) @@ -5332,6 +5365,19 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal) (call_param_p ? EXPAND_STACK_PARM : EXPAND_NORMAL), &alt_rtl, false); + + /* Handle bounds returned by call. */ + if (TREE_CODE (exp) == CALL_EXPR) + { + rtx bounds; + chkp_split_slot (temp, &temp, &bounds); + if (bounds && btarget) + { + gcc_assert (TREE_CODE (btarget) == SSA_NAME); + rtx tmp = targetm.calls.load_returned_bounds (bounds); + chkp_set_rtl_bounds (btarget, tmp); + } + } } /* If TEMP is a VOIDmode constant and the mode of the type of EXP is not @@ -5496,6 +5542,13 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal) return NULL_RTX; } + +/* Same as store_expr_with_bounds but ignoring bounds of EXP. */ +rtx +store_expr (tree exp, rtx target, int call_param_p, bool nontemporal) +{ + return store_expr_with_bounds (exp, target, call_param_p, nontemporal, NULL); +} /* Return true if field F of structure TYPE is a flexible array. */ |