diff options
author | Ilya Enkovich <ilya.enkovich@intel.com> | 2015-06-01 11:24:07 +0000 |
---|---|---|
committer | Ilya Enkovich <ienkovich@gcc.gnu.org> | 2015-06-01 11:24:07 +0000 |
commit | 8e9b2773979616d97a18977bb2fb8cab75fd1e60 (patch) | |
tree | 20d751c59fc8cbfe3db9985d594e401492c12d91 /gcc/tree-chkp.c | |
parent | f4fa7bb4733608417a7f2d934f001e6fd69c1cf8 (diff) | |
download | gcc-8e9b2773979616d97a18977bb2fb8cab75fd1e60.zip gcc-8e9b2773979616d97a18977bb2fb8cab75fd1e60.tar.gz gcc-8e9b2773979616d97a18977bb2fb8cab75fd1e60.tar.bz2 |
re PR target/65527 (ICE: in expand_builtin_with_bounds, at builtins.c:7120 with -fcheck-pointer-bounds -mmpx)
gcc/
PR target/65527
* cgraph.c (cgraph_edge::redirect_call_stmt_to_callee): Add
redirection for instrumented calls.
* lto-wrapper.c (merge_and_complain): Merge -fcheck-pointer-bounds.
(append_compiler_options): Append -fcheck-pointer-bounds.
* tree-chkp.h (chkp_copy_call_skip_bounds): New.
(chkp_redirect_edge): New.
* tree-chkp.c (chkp_copy_call_skip_bounds): New.
(chkp_redirect_edge): New.
gcc/testsuite/
PR target/65527
* gcc.target/i386/mpx/chkp-fix-calls-1.c: New.
* gcc.target/i386/mpx/chkp-fix-calls-2.c: New.
* gcc.target/i386/mpx/chkp-fix-calls-3.c: New.
* gcc.target/i386/mpx/chkp-fix-calls-4.c: New.
From-SVN: r223929
Diffstat (limited to 'gcc/tree-chkp.c')
-rw-r--r-- | gcc/tree-chkp.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c index 88c1f45..015df11 100644 --- a/gcc/tree-chkp.c +++ b/gcc/tree-chkp.c @@ -529,6 +529,71 @@ chkp_insert_retbnd_call (tree bndval, tree retval, return bndval; } +/* Build a GIMPLE_CALL identical to CALL but skipping bounds + arguments. */ + +gcall * +chkp_copy_call_skip_bounds (gcall *call) +{ + bitmap bounds; + unsigned i; + + bitmap_obstack_initialize (NULL); + bounds = BITMAP_ALLOC (NULL); + + for (i = 0; i < gimple_call_num_args (call); i++) + if (POINTER_BOUNDS_P (gimple_call_arg (call, i))) + bitmap_set_bit (bounds, i); + + if (!bitmap_empty_p (bounds)) + call = gimple_call_copy_skip_args (call, bounds); + gimple_call_set_with_bounds (call, false); + + BITMAP_FREE (bounds); + bitmap_obstack_release (NULL); + + return call; +} + +/* Redirect edge E to the correct node according to call_stmt. + Return 1 if bounds removal from call_stmt should be done + instead of redirection. */ + +bool +chkp_redirect_edge (cgraph_edge *e) +{ + bool instrumented = false; + tree decl = e->callee->decl; + + if (e->callee->instrumentation_clone + || chkp_function_instrumented_p (decl)) + instrumented = true; + + if (instrumented + && !gimple_call_with_bounds_p (e->call_stmt)) + e->redirect_callee (cgraph_node::get_create (e->callee->orig_decl)); + else if (!instrumented + && gimple_call_with_bounds_p (e->call_stmt) + && !chkp_gimple_call_builtin_p (e->call_stmt, BUILT_IN_CHKP_BNDCL) + && !chkp_gimple_call_builtin_p (e->call_stmt, BUILT_IN_CHKP_BNDCU) + && !chkp_gimple_call_builtin_p (e->call_stmt, BUILT_IN_CHKP_BNDSTX)) + { + if (e->callee->instrumented_version) + e->redirect_callee (e->callee->instrumented_version); + else + { + tree args = TYPE_ARG_TYPES (TREE_TYPE (decl)); + /* Avoid bounds removal if all args will be removed. */ + if (!args || TREE_VALUE (args) != void_type_node) + return true; + else + gimple_call_set_with_bounds (e->call_stmt, false); + } + } + + return false; +} + /* Mark statement S to not be instrumented. */ static void chkp_mark_stmt (gimple s) |