aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorienkovich <ienkovich@138bc75d-0d04-0410-961f-82ee72b054a4>2015-06-18 10:14:38 +0000
committerienkovich <ienkovich@138bc75d-0d04-0410-961f-82ee72b054a4>2015-06-18 10:14:38 +0000
commit2e6c9e14a688c97e8277306166c069a0137ee992 (patch)
tree555dbafe475f14c973a8d7cf45e60c09bd75dc1f
parent391cf42b668f79f2c0dc58fb9314a179048f580b (diff)
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@224601 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/cfgexpand.c92
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/i386/mpx/pr66568.c10
-rw-r--r--gcc/tree-chkp.c15
-rw-r--r--gcc/tree-chkp.h1
6 files changed, 96 insertions, 35 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 335ec7dbddc..23301d4beee 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,13 @@
2015-06-18 Ilya Enkovich <enkovich.gnu@gmail.com>
+ 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.
+
+2015-06-18 Ilya Enkovich <enkovich.gnu@gmail.com>
+
PR middle-end/66567
* ipa-chkp.c (chkp_maybe_create_clone): Require
functions to be instrumentable.
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 06755d5491c..6b79b1dae77 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:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 95107ae6681..3b1d0710c1a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
2015-06-18 Ilya Enkovich <enkovich.gnu@gmail.com>
+ PR middle-end/66568
+ * gcc.target/i386/mpx/pr66568.c: New test.
+
+2015-06-18 Ilya Enkovich <enkovich.gnu@gmail.com>
+
PR middle-end/66567
* gcc.target/i386/mpx/pr66567.c: New test.
diff --git a/gcc/testsuite/gcc.target/i386/mpx/pr66568.c b/gcc/testsuite/gcc.target/i386/mpx/pr66568.c
new file mode 100644
index 00000000000..d7bb9f6e31d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/pr66568.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target fpic } */
+/* { dg-options "-O2 -fcheck-pointer-bounds -mmpx -O2 -fPIC" } */
+
+int a, b, c;
+void *set_test () {
+ if (b)
+ a ? exit (0) : exit (1);
+ b = c;
+}
diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
index ed734e649c4..7ffec7b6305 100644
--- a/gcc/tree-chkp.c
+++ b/gcc/tree-chkp.c
@@ -466,6 +466,21 @@ chkp_gimple_call_builtin_p (gimple call,
return false;
}
+/* Emit code to build zero bounds and return RTL holding
+ the result. */
+rtx
+chkp_expand_zero_bounds ()
+{
+ tree zero_bnd;
+
+ if (flag_chkp_use_static_const_bounds)
+ zero_bnd = chkp_get_zero_bounds_var ();
+ else
+ zero_bnd = chkp_build_make_bounds_call (integer_zero_node,
+ integer_zero_node);
+ return expand_normal (zero_bnd);
+}
+
/* Emit code to store zero bounds for PTR located at MEM. */
void
chkp_expand_bounds_reset_for_mem (tree mem, tree ptr)
diff --git a/gcc/tree-chkp.h b/gcc/tree-chkp.h
index b5ab56252ed..6e41086ebe4 100644
--- a/gcc/tree-chkp.h
+++ b/gcc/tree-chkp.h
@@ -53,6 +53,7 @@ extern void chkp_copy_bounds_for_assign (gimple assign,
struct cgraph_edge *edge);
extern bool chkp_gimple_call_builtin_p (gimple call,
enum built_in_function code);
+extern rtx chkp_expand_zero_bounds (void);
extern void chkp_expand_bounds_reset_for_mem (tree mem, tree ptr);
extern tree chkp_insert_retbnd_call (tree bndval, tree retval,
gimple_stmt_iterator *gsi);