[PATCH, Pointer Bounds Checker 37/x] Support va_arg_pack and va_arg_pack_len

Ilya Enkovich enkovich.gnu@gmail.com
Mon Aug 18 15:03:00 GMT 2014


Hi,

This patch adds support for va_arg_pack and va_arg_pack_len for instrumented functions into inliner.  There are two things to do: 1) ignore bounds args when computing va_arg_pack_len 2) remove bounds args when expanding va_arg_pack in not instrumented call.

Thanks,
Ilya
--
2014-08-15  Ilya Enkovich  <ilya.enkovich@intel.com>

	* tree-inline.c (copy_bb): Properly handle bounds in
	va_arg_pack and va_arg_pack_len.


diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 6ec1a81..03e7e2f 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1767,13 +1767,29 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
 	      gimple new_call;
 	      vec<tree> argarray;
 	      size_t nargs = gimple_call_num_args (id->gimple_call);
-	      size_t n;
+	      size_t n, i, nargs_to_copy;
+	      bool remove_bounds = false;
 
 	      for (p = DECL_ARGUMENTS (id->src_fn); p; p = DECL_CHAIN (p))
 		nargs--;
 
+	      /* Bounds should be removed from arg pack in case
+		 we handle not instrumented call in instrumented
+		 function.  */
+	      nargs_to_copy = nargs;
+	      if (gimple_call_with_bounds_p (id->gimple_call)
+		  && !gimple_call_with_bounds_p (stmt))
+		{
+		  for (i = gimple_call_num_args (id->gimple_call) - nargs;
+		       i < gimple_call_num_args (id->gimple_call);
+		       i++)
+		    if (POINTER_BOUNDS_P (gimple_call_arg (id->gimple_call, i)))
+		      nargs_to_copy--;
+		  remove_bounds = true;
+		}
+
 	      /* Create the new array of arguments.  */
-	      n = nargs + gimple_call_num_args (stmt);
+	      n = nargs_to_copy + gimple_call_num_args (stmt);
 	      argarray.create (n);
 	      argarray.safe_grow_cleared (n);
 
@@ -1782,11 +1798,26 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
 		      gimple_call_arg_ptr (stmt, 0),
 		      gimple_call_num_args (stmt) * sizeof (tree));
 
-	      /* Append the arguments passed in '...'  */
-	      memcpy (argarray.address () + gimple_call_num_args (stmt),
-		      gimple_call_arg_ptr (id->gimple_call, 0)
-			+ (gimple_call_num_args (id->gimple_call) - nargs),
-		      nargs * sizeof (tree));
+	      if (remove_bounds)
+		{
+		  /* Append the rest of arguments removing bounds.  */
+		  unsigned cur = gimple_call_num_args (stmt);
+		  i = gimple_call_num_args (id->gimple_call) - nargs;
+		  for (i = gimple_call_num_args (id->gimple_call) - nargs;
+		       i < gimple_call_num_args (id->gimple_call);
+		       i++)
+		    if (!POINTER_BOUNDS_P (gimple_call_arg (id->gimple_call, i)))
+		      argarray[cur++] = gimple_call_arg (id->gimple_call, i);
+		  gcc_assert (cur == n);
+		}
+	      else
+		{
+		  /* Append the arguments passed in '...'  */
+		  memcpy (argarray.address () + gimple_call_num_args (stmt),
+			  gimple_call_arg_ptr (id->gimple_call, 0)
+			  + (gimple_call_num_args (id->gimple_call) - nargs),
+			  nargs * sizeof (tree));
+		}
 
 	      new_call = gimple_build_call_vec (gimple_call_fn (stmt),
 						argarray);
@@ -1812,13 +1843,20 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
 	    {
 	      /* __builtin_va_arg_pack_len () should be replaced by
 		 the number of anonymous arguments.  */
-	      size_t nargs = gimple_call_num_args (id->gimple_call);
+	      size_t nargs = gimple_call_num_args (id->gimple_call), i;
 	      tree count, p;
 	      gimple new_stmt;
 
 	      for (p = DECL_ARGUMENTS (id->src_fn); p; p = DECL_CHAIN (p))
 		nargs--;
 
+	      /* For instrumented calls we should ignore bounds.  */
+	      for (i = gimple_call_num_args (id->gimple_call) - nargs;
+		   i < gimple_call_num_args (id->gimple_call);
+		   i++)
+		if (POINTER_BOUNDS_P (gimple_call_arg (id->gimple_call, i)))
+		  nargs--;
+
 	      count = build_int_cst (integer_type_node, nargs);
 	      new_stmt = gimple_build_assign (gimple_call_lhs (stmt), count);
 	      gsi_replace (&copy_gsi, new_stmt, false);



More information about the Gcc-patches mailing list