aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-chkp.c
diff options
context:
space:
mode:
authorIlya Enkovich <ilya.enkovich@intel.com>2015-06-01 11:24:07 +0000
committerIlya Enkovich <ienkovich@gcc.gnu.org>2015-06-01 11:24:07 +0000
commit8e9b2773979616d97a18977bb2fb8cab75fd1e60 (patch)
tree20d751c59fc8cbfe3db9985d594e401492c12d91 /gcc/tree-chkp.c
parentf4fa7bb4733608417a7f2d934f001e6fd69c1cf8 (diff)
downloadgcc-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.c65
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)