This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix and improve tree-object-size.c pass_through_call
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Biener <rguenther at suse dot de>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Thu, 23 Nov 2017 21:30:11 +0100
- Subject: [PATCH] Fix and improve tree-object-size.c pass_through_call
- Authentication-results: sourceware.org; auth=none
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
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