diff options
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cfgexpand.c | 92 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/mpx/pr66568.c | 10 | ||||
-rw-r--r-- | gcc/tree-chkp.c | 15 | ||||
-rw-r--r-- | gcc/tree-chkp.h | 1 |
6 files changed, 96 insertions, 35 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 335ec7d..23301d4 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 06755d5..6b79b1d 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 95107ae..3b1d071 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 0000000..d7bb9f6 --- /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 ed734e6..7ffec7b 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 b5ab562..6e41086 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); |