From 64a948e9c2c34aea10e5a995f9e67bb6325ca7e8 Mon Sep 17 00:00:00 2001 From: Ilya Enkovich Date: Thu, 10 Dec 2015 16:01:42 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 10 +++++++ gcc/tree-chkp.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++- gcc/tree-chkp.h | 1 + gcc/tree-stdarg.c | 6 +++++ 4 files changed, 85 insertions(+), 1 deletion(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6e45dc565ad..4cd1567ff84 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2015-12-10 Ilya Enkovich + + * 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 * tree-inline.c (duplicate_remap_omp_clause_seq): New function. diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c index 8b6381f7bb9..b666e970643 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 (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 cc248584d28..9337eb734df 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 f205ccbec9a..ea2ef1c4f1b 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 -- 2.30.2