summaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c71
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. */