Hi Richard, Following your suggestion in PR78154, the patch checks if stmt contains call to memmove (and friends) in gimple_stmt_nonzero_warnv_p and returns true in that case.
Bootstrapped+tested on x86_64-unknown-linux-gnu. Cross-testing on arm*-*-*, aarch64*-*-* in progress. Would it be OK to commit this patch in stage-3 ? Thanks, Prathamesh
2016-11-17 Prathamesh Kulkarni <prathamesh.kulka...@linaro.org> * tree-vrp.c (gimple_str_nonzero_warnv_p): New function. (gimple_stmt_nonzero_warnv_p): Call gimple_str_nonzero_warnv_p. testsuite/ * gcc.dg/tree-ssa/pr78154.c: New test-case. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr78154.c b/gcc/testsuite/gcc.dg/tree-ssa/pr78154.c new file mode 100644 index 0000000..d3463f4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr78154.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-evrp-slim" } */ + +void f (void *d, const void *s, __SIZE_TYPE__ n) +{ + if (__builtin_memcpy (d, s, n) == 0) + __builtin_abort (); + + if (__builtin_memmove (d, s, n) == 0) + __builtin_abort (); + + if (__builtin_memset (d, 0, n) == 0) + __builtin_abort (); + + if (__builtin_strcpy (d, s) == 0) + __builtin_abort (); + + if (__builtin_strcat (d, s) == 0) + __builtin_abort (); + + if (__builtin_strncpy (d, s, n) == 0) + __builtin_abort (); + + if (__builtin_strncat (d, s, n) == 0) + __builtin_abort (); +} + +/* { dg-final { scan-tree-dump-not "__builtin_abort" "evrp" } } */ diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index c2a4133..b563a7f 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -1069,6 +1069,34 @@ gimple_assign_nonzero_warnv_p (gimple *stmt, bool *strict_overflow_p) } } +/* Return true if STMT is known to contain call to a string-builtin function + that is known to return nonnull. */ + +static bool +gimple_str_nonzero_warnv_p (gimple *stmt) +{ + if (!is_gimple_call (stmt)) + return false; + + tree fndecl = gimple_call_fndecl (stmt); + if (!fndecl || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL) + return false; + + switch (DECL_FUNCTION_CODE (fndecl)) + { + case BUILT_IN_MEMMOVE: + case BUILT_IN_MEMCPY: + case BUILT_IN_MEMSET: + case BUILT_IN_STRCPY: + case BUILT_IN_STRNCPY: + case BUILT_IN_STRCAT: + case BUILT_IN_STRNCAT: + return true; + default: + return false; + } +} + /* Return true if STMT is known to compute a non-zero value. If the return value is based on the assumption that signed overflow is undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't change @@ -1097,7 +1125,7 @@ gimple_stmt_nonzero_warnv_p (gimple *stmt, bool *strict_overflow_p) lookup_attribute ("returns_nonnull", TYPE_ATTRIBUTES (gimple_call_fntype (stmt)))) return true; - return gimple_alloca_call_p (stmt); + return gimple_alloca_call_p (stmt) || gimple_str_nonzero_warnv_p (stmt); } default: gcc_unreachable ();