aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIlya Enkovich <enkovich.gnu@gmail.com>2015-12-10 16:01:42 +0000
committerIlya Enkovich <ienkovich@gcc.gnu.org>2015-12-10 16:01:42 +0000
commit64a948e9c2c34aea10e5a995f9e67bb6325ca7e8 (patch)
tree933bb83d196ac3eeaa156a457f6a2b08e24ee50a /gcc
parentda8006f341fc2a30d32fe7a1d9d540617ff5f8b6 (diff)
downloadgcc-64a948e9c2c34aea10e5a995f9e67bb6325ca7e8.zip
gcc-64a948e9c2c34aea10e5a995f9e67bb6325ca7e8.tar.gz
gcc-64a948e9c2c34aea10e5a995f9e67bb6325ca7e8.tar.bz2
tree-chkp.c (chkp_call_returns_bounds_p): Return true for VA_ARG call.
gcc/ * tree-chkp.c (chkp_call_returns_bounds_p): Return true for VA_ARG call. (chkp_fixup_inlined_call): New. * tree-chkp.h (chkp_fixup_inlined_call): New. * tree-stdarg.c: Include tree-chkp.h. (expand_ifn_va_arg_1): Fixup bndret calls for removed VA_ARG calls. From-SVN: r231525
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/tree-chkp.c69
-rw-r--r--gcc/tree-chkp.h1
-rw-r--r--gcc/tree-stdarg.c6
4 files changed, 85 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6e45dc5..4cd1567 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2015-12-10 Ilya Enkovich <enkovich.gnu@gmail.com>
+
+ * tree-chkp.c (chkp_call_returns_bounds_p): Return true
+ for VA_ARG call.
+ (chkp_fixup_inlined_call): New.
+ * tree-chkp.h (chkp_fixup_inlined_call): New.
+ * tree-stdarg.c: Include tree-chkp.h.
+ (expand_ifn_va_arg_1): Fixup bndret calls for removed
+ VA_ARG calls.
+
2015-12-10 Martin Jambor <mjambor@suse.cz>
* tree-inline.c (duplicate_remap_omp_clause_seq): New function.
diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
index 8b6381f..b666e97 100644
--- a/gcc/tree-chkp.c
+++ b/gcc/tree-chkp.c
@@ -2157,7 +2157,11 @@ static bool
chkp_call_returns_bounds_p (gcall *call)
{
if (gimple_call_internal_p (call))
- return false;
+ {
+ if (gimple_call_internal_fn (call) == IFN_VA_ARG)
+ return true;
+ return false;
+ }
if (gimple_call_builtin_p (call, BUILT_IN_CHKP_NARROW_PTR_BOUNDS)
|| chkp_gimple_call_builtin_p (call, BUILT_IN_CHKP_NARROW))
@@ -2490,6 +2494,69 @@ chkp_build_bndstx (tree addr, tree ptr, tree bounds,
}
}
+/* This function is called when call statement
+ is inlined and therefore we can't use bndret
+ for its LHS anymore. Function fixes bndret
+ call using new RHS value if possible. */
+void
+chkp_fixup_inlined_call (tree lhs, tree rhs)
+{
+ tree addr, bounds;
+ gcall *retbnd, *bndldx;
+
+ if (!BOUNDED_P (lhs))
+ return;
+
+ /* Search for retbnd call. */
+ retbnd = chkp_retbnd_call_by_val (lhs);
+ if (!retbnd)
+ return;
+
+ /* Currently only handle cases when call is replaced
+ with a memory access. In this case bndret call
+ may be replaced with bndldx call. Otherwise we
+ have to search for bounds which may cause wrong
+ result due to various optimizations applied. */
+ switch (TREE_CODE (rhs))
+ {
+ case VAR_DECL:
+ if (DECL_REGISTER (rhs))
+ return;
+ break;
+
+ case MEM_REF:
+ break;
+
+ case ARRAY_REF:
+ case COMPONENT_REF:
+ addr = get_base_address (rhs);
+ if (!DECL_P (addr)
+ && TREE_CODE (addr) != MEM_REF)
+ return;
+ if (DECL_P (addr) && DECL_REGISTER (addr))
+ return;
+ break;
+
+ default:
+ return;
+ }
+
+ /* Create a new statements sequence with bndldx call. */
+ gimple_stmt_iterator gsi = gsi_for_stmt (retbnd);
+ addr = build_fold_addr_expr (rhs);
+ chkp_build_bndldx (addr, lhs, &gsi);
+ bndldx = as_a <gcall *> (gsi_stmt (gsi));
+
+ /* Remove bndret call. */
+ bounds = gimple_call_lhs (retbnd);
+ gsi = gsi_for_stmt (retbnd);
+ gsi_remove (&gsi, true);
+
+ /* Link new bndldx call. */
+ gimple_call_set_lhs (bndldx, bounds);
+ update_stmt (bndldx);
+}
+
/* Compute bounds for pointer NODE which was assigned in
assignment statement ASSIGN. Return computed bounds. */
static tree
diff --git a/gcc/tree-chkp.h b/gcc/tree-chkp.h
index cc24858..9337eb7 100644
--- a/gcc/tree-chkp.h
+++ b/gcc/tree-chkp.h
@@ -59,5 +59,6 @@ extern tree chkp_insert_retbnd_call (tree bndval, tree retval,
gimple_stmt_iterator *gsi);
extern gcall *chkp_copy_call_skip_bounds (gcall *call);
extern bool chkp_redirect_edge (cgraph_edge *e);
+extern void chkp_fixup_inlined_call (tree lhs, tree rhs);
#endif /* GCC_TREE_CHKP_H */
diff --git a/gcc/tree-stdarg.c b/gcc/tree-stdarg.c
index f205ccb..ea2ef1c 100644
--- a/gcc/tree-stdarg.c
+++ b/gcc/tree-stdarg.c
@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-into-ssa.h"
#include "tree-cfg.h"
#include "tree-stdarg.h"
+#include "tree-chkp.h"
/* A simple pass that attempts to optimize stdarg functions on architectures
that need to save register arguments to stack on entry to stdarg functions.
@@ -1047,6 +1048,11 @@ expand_ifn_va_arg_1 (function *fun)
unsigned int nargs = gimple_call_num_args (stmt);
gcc_assert (useless_type_conversion_p (TREE_TYPE (lhs), type));
+ /* We replace call with a new expr. This may require
+ corresponding bndret call fixup. */
+ if (chkp_function_instrumented_p (fun->decl))
+ chkp_fixup_inlined_call (lhs, expr);
+
if (nargs == 3)
{
/* We've transported the size of with WITH_SIZE_EXPR here as