This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix and improve tree-object-size.c pass_through_call


Hi!

As mentioned on IRC, we can actually now use ERF_RETURN*_ARG* to find out
what functions are pass through (except for __builtin_assume_aligned, which
is pass through but we never want to propagate the arg to the result early, as
the result contains additional information, so it isn't RET1).

While cleaning this up, I run into a bug in the function, BUILT_IN_STPNCPY_CHK
obviously isn't a pass-through function, so I've also added a testcase that
FAILs without this patch and succeeds with it.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

For release branches I'd just remove the BUILT_IN_STPNCPY_CHK case and
add testcase.

2017-11-23  Jakub Jelinek  <jakub@redhat.com>

	* tree-object-size.c (pass_through_call): Use gimple_call_return_flags
	ERF_RETURN*ARG* for builtins other than BUILT_IN_ASSUME_ALIGNED,
	check for the latter with gimple_call_builtin_p.  Do not handle
	BUILT_IN_STPNCPY_CHK which is not a pass through call.

	* gcc.dg/builtin-object-size-18.c: New test.

--- gcc/tree-object-size.c.jj	2017-10-20 09:16:10.000000000 +0200
+++ gcc/tree-object-size.c	2017-11-23 16:23:24.544741945 +0100
@@ -464,34 +464,17 @@ alloc_object_size (const gcall *call, in
 static tree
 pass_through_call (const gcall *call)
 {
-  tree callee = gimple_call_fndecl (call);
+  unsigned rf = gimple_call_return_flags (call);
+  if (rf & ERF_RETURNS_ARG)
+    {
+      unsigned argnum = rf & ERF_RETURN_ARG_MASK;
+      if (argnum < gimple_call_num_args (call))
+	return gimple_call_arg (call, argnum);
+    }
 
-  if (callee
-      && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
-    switch (DECL_FUNCTION_CODE (callee))
-      {
-      case BUILT_IN_MEMCPY:
-      case BUILT_IN_MEMMOVE:
-      case BUILT_IN_MEMSET:
-      case BUILT_IN_STRCPY:
-      case BUILT_IN_STRNCPY:
-      case BUILT_IN_STRCAT:
-      case BUILT_IN_STRNCAT:
-      case BUILT_IN_MEMCPY_CHK:
-      case BUILT_IN_MEMMOVE_CHK:
-      case BUILT_IN_MEMSET_CHK:
-      case BUILT_IN_STRCPY_CHK:
-      case BUILT_IN_STRNCPY_CHK:
-      case BUILT_IN_STPNCPY_CHK:
-      case BUILT_IN_STRCAT_CHK:
-      case BUILT_IN_STRNCAT_CHK:
-      case BUILT_IN_ASSUME_ALIGNED:
-	if (gimple_call_num_args (call) >= 1)
-	  return gimple_call_arg (call, 0);
-	break;
-      default:
-	break;
-      }
+  /* __builtin_assume_aligned is intentionally not marked RET1.  */
+  if (gimple_call_builtin_p (call, BUILT_IN_ASSUME_ALIGNED))
+    return gimple_call_arg (call, 0);
 
   return NULL_TREE;
 }
--- gcc/testsuite/gcc.dg/builtin-object-size-18.c.jj	2017-11-23 16:33:25.723389685 +0100
+++ gcc/testsuite/gcc.dg/builtin-object-size-18.c	2017-11-23 16:34:02.930934647 +0100
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* __stpncpy_chk could return buf up to buf + 64, so
+   the minimum object size might be far smaller than 64.  */
+/* { dg-final { scan-tree-dump-not "return 64;" "optimized" } } */
+
+typedef __SIZE_TYPE__ size_t;
+
+size_t
+foo (const char *p, size_t s, size_t t)
+{
+  char buf[64];
+  char *q = __builtin___stpncpy_chk (buf, p, s, t);
+  return __builtin_object_size (q, 2);
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]