tree-chkp.c (chkp_call_returns_bounds_p): Return true for VA_ARG call.
authorIlya Enkovich <enkovich.gnu@gmail.com>
Thu, 10 Dec 2015 16:01:42 +0000 (16:01 +0000)
committerIlya Enkovich <ienkovich@gcc.gnu.org>
Thu, 10 Dec 2015 16:01:42 +0000 (16:01 +0000)
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
gcc/tree-chkp.c
gcc/tree-chkp.h
gcc/tree-stdarg.c

index 6e45dc5..4cd1567 100644 (file)
@@ -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.
index 8b6381f..b666e97 100644 (file)
@@ -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
index cc24858..9337eb7 100644 (file)
@@ -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 */
index f205ccb..ea2ef1c 100644 (file)
@@ -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