diff mbox

Fix PR78154

Message ID CAAgBjM=8XdT_-EzUXodT5YoWdttUT2yzJM4yc20nfieJZhWAdg@mail.gmail.com
State Superseded
Headers show

Commit Message

Prathamesh Kulkarni Nov. 22, 2016, 10:14 a.m. UTC
On 21 November 2016 at 15:34, Richard Biener <rguenther@suse.de> wrote:
> On Fri, 18 Nov 2016, Prathamesh Kulkarni wrote:

>

>> On 17 November 2016 at 15:24, Richard Biener <rguenther@suse.de> wrote:

>> > On Thu, 17 Nov 2016, Prathamesh Kulkarni wrote:

>> >

>> >> On 17 November 2016 at 14:21, Richard Biener <rguenther@suse.de> wrote:

>> >> > On Thu, 17 Nov 2016, Prathamesh Kulkarni wrote:

>> >> >

>> >> >> 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 ?

>> >> >

>> >> > As people noted we have returns_nonnull for this and that is already

>> >> > checked.  So please make sure the builtins get this attribute instead.

>> >> OK thanks, I will add the returns_nonnull attribute to the required

>> >> string builtins.

>> >> I noticed some of the string builtins don't have RET1 in builtins.def:

>> >> strcat, strncpy, strncat have ATTR_NOTHROW_NONNULL_LEAF.

>> >> Should they instead be having ATTR_RET1_NOTHROW_NONNULL_LEAF similar

>> >> to entries for memmove, strcpy ?

>> >

>> > Yes, I think so.

>> Hi,

>> In the attached patch I added returns_nonnull attribute to

>> ATTR_RET1_NOTHROW_NONNULL_LEAF,

>> and changed few builtins like strcat, strncpy, strncat and

>> corresponding _chk builtins to use ATTR_RET1_NOTHROW_NONNULL_LEAF.

>> Does the patch look correct ?

>

> Hmm, given you only change ATTR_RET1_NOTHROW_NONNULL_LEAF means that

> the gimple_stmt_nonzero_warnv_p code is incomplete -- it should

> infer returns_nonnull itself from RET1 (which is fnspec("1") basically)

> and the nonnull attribute on the argument.  So

>

>   unsigned rf = gimple_call_return_flags (stmt);

>   if (rf & ERF_RETURNS_ARG)

>    {

>      tree arg = gimple_call_arg (stmt, rf & ERF_RETURN_ARG_MASK);

>      if (range of arg is ! VARYING)

>        use range of arg;

>      else if (infer_nonnull_range_by_attribute (stmt, arg))

>         ... nonnull ...

>

Hi,
Thanks for the suggestions, modified gimple_stmt_nonzero_warnv_p
accordingly in this version.
For functions like stpcpy that return nonnull but not one of it's
arguments, I added new enum ATTR_RETNONNULL_NOTHROW_LEAF.
Is that OK ?
Bootstrapped+tested on x86_64-unknown-linux-gnu.
Cross-testing on arm*-*-*, aarch64*-*-* in progress.

Thanks,
Prathamesh
> Richard.

>

>> Thanks,

>> Prathamesh

>> >

>> > Richard.

>>

>

> --

> Richard Biener <rguenther@suse.de>

> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)
2016-11-22  Richard Biener  <rguenther@suse.de>
	    Prathamesh Kulkarni  <prathamesh.kulkarni@linaro.rog>

	* tree-vrp.c (gimple_stmt_nonzero_warnv_p): Return true if function
	returns it's argument and the argument is nonnull.
	* builtin-attrs.def: Define ATTR_RETURNS_NONNULL,
	ATT_RETNONNULL_NOTHROW_LEAF.
	* builtins.def (BUILT_IN_MEMPCPY): Change attribute to
	ATTR_RETNONNULL_NOTHROW_LEAF.
	(BUILT_IN_STPCPY): Likewise.
	(BUILT_IN_STPNCPY): Likewise.
	(BUILT_IN_MEMPCPY_CHK): Likewise.
	(BUILT_IN_STPCPY_CHK): Likewise.
	(BUILT_IN_STPNCPY_CHK): Likewise.
	(BUILT_IN_STRCAT): Change attribute to ATTR_RET1_NOTHROW_NONNULL_LEAF.
	(BUILT_IN_STRNCAT): Likewise.
	(BUILT_IN_STRNCPY): Likewise.
	(BUILT_IN_MEMSET_CHK): Likewise.
	(BUILT_IN_STRCAT_CHK): Likewise.
	(BUILT_IN_STRCPY_CHK): Likewise.
	(BUILT_IN_STRNCAT_CHK): Likewise.
	(BUILT_IN_STRNCPY_CHK): Likewise.

testsuite/
	* gcc.dg/tree-ssa/pr78154.c: New test.

Comments

Richard Biener Nov. 22, 2016, 2:53 p.m. UTC | #1
On Tue, 22 Nov 2016, Prathamesh Kulkarni wrote:

> On 21 November 2016 at 15:34, Richard Biener <rguenther@suse.de> wrote:

> > On Fri, 18 Nov 2016, Prathamesh Kulkarni wrote:

> >

> >> On 17 November 2016 at 15:24, Richard Biener <rguenther@suse.de> wrote:

> >> > On Thu, 17 Nov 2016, Prathamesh Kulkarni wrote:

> >> >

> >> >> On 17 November 2016 at 14:21, Richard Biener <rguenther@suse.de> wrote:

> >> >> > On Thu, 17 Nov 2016, Prathamesh Kulkarni wrote:

> >> >> >

> >> >> >> 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 ?

> >> >> >

> >> >> > As people noted we have returns_nonnull for this and that is already

> >> >> > checked.  So please make sure the builtins get this attribute instead.

> >> >> OK thanks, I will add the returns_nonnull attribute to the required

> >> >> string builtins.

> >> >> I noticed some of the string builtins don't have RET1 in builtins.def:

> >> >> strcat, strncpy, strncat have ATTR_NOTHROW_NONNULL_LEAF.

> >> >> Should they instead be having ATTR_RET1_NOTHROW_NONNULL_LEAF similar

> >> >> to entries for memmove, strcpy ?

> >> >

> >> > Yes, I think so.

> >> Hi,

> >> In the attached patch I added returns_nonnull attribute to

> >> ATTR_RET1_NOTHROW_NONNULL_LEAF,

> >> and changed few builtins like strcat, strncpy, strncat and

> >> corresponding _chk builtins to use ATTR_RET1_NOTHROW_NONNULL_LEAF.

> >> Does the patch look correct ?

> >

> > Hmm, given you only change ATTR_RET1_NOTHROW_NONNULL_LEAF means that

> > the gimple_stmt_nonzero_warnv_p code is incomplete -- it should

> > infer returns_nonnull itself from RET1 (which is fnspec("1") basically)

> > and the nonnull attribute on the argument.  So

> >

> >   unsigned rf = gimple_call_return_flags (stmt);

> >   if (rf & ERF_RETURNS_ARG)

> >    {

> >      tree arg = gimple_call_arg (stmt, rf & ERF_RETURN_ARG_MASK);

> >      if (range of arg is ! VARYING)

> >        use range of arg;

> >      else if (infer_nonnull_range_by_attribute (stmt, arg))

> >         ... nonnull ...

> >

> Hi,

> Thanks for the suggestions, modified gimple_stmt_nonzero_warnv_p

> accordingly in this version.

> For functions like stpcpy that return nonnull but not one of it's

> arguments, I added new enum ATTR_RETNONNULL_NOTHROW_LEAF.

> Is that OK ?

> Bootstrapped+tested on x86_64-unknown-linux-gnu.

> Cross-testing on arm*-*-*, aarch64*-*-* in progress.


+               value_range *vr = get_value_range (arg);
+               if ((vr && vr->type != VR_VARYING)
+                   || infer_nonnull_range_by_attribute (stmt, arg))
+                 return true;
+             }

actually that's not quite correct (failed to notice the function
doesn't return a range but whether the range is nonnull).  For
nonnull it's just

  if (infer_nonnull_range_by_attribute (stmt, arg))
    return true;

in the extract_range_basic call handling we could handle
ERF_RETURNS_ARG by returning the range of the argument (if not varying).

Thus the patch is ok with the above condition changed.  Please refer
to the recently opened PR from the ChangeLog.

Thanks,
Richard.
diff mbox

Patch

diff --git a/gcc/builtin-attrs.def b/gcc/builtin-attrs.def
index 8dc59c9..94d0c62 100644
--- a/gcc/builtin-attrs.def
+++ b/gcc/builtin-attrs.def
@@ -108,6 +108,7 @@  DEF_ATTR_IDENT (ATTR_TYPEGENERIC, "type generic")
 DEF_ATTR_IDENT (ATTR_TM_REGPARM, "*tm regparm")
 DEF_ATTR_IDENT (ATTR_TM_TMPURE, "transaction_pure")
 DEF_ATTR_IDENT (ATTR_RETURNS_TWICE, "returns_twice")
+DEF_ATTR_IDENT (ATTR_RETURNS_NONNULL, "returns_nonnull")
 
 DEF_ATTR_TREE_LIST (ATTR_NOVOPS_LIST, ATTR_NOVOPS, ATTR_NULL, ATTR_NULL)
 
@@ -197,6 +198,9 @@  DEF_ATTR_TREE_LIST (ATTR_CONST_NOTHROW_NONNULL, ATTR_CONST, ATTR_NULL, \
    and which return their first argument.  */
 DEF_ATTR_TREE_LIST (ATTR_RET1_NOTHROW_NONNULL_LEAF, ATTR_FNSPEC, ATTR_LIST_STR1, \
 			ATTR_NOTHROW_NONNULL_LEAF)
+/* Nothrow leaf functions whose return value is nonnull.  */
+DEF_ATTR_TREE_LIST (ATTR_RETNONNULL_NOTHROW_LEAF, ATTR_RETURNS_NONNULL, ATTR_NULL, \
+			ATTR_NOTHROW_LEAF_LIST)
 /* Nothrow const leaf functions whose pointer parameter(s) are all nonnull.  */
 DEF_ATTR_TREE_LIST (ATTR_CONST_NOTHROW_NONNULL_LEAF, ATTR_CONST, ATTR_NULL, \
 			ATTR_NOTHROW_NONNULL_LEAF)

diff --git a/gcc/builtins.def b/gcc/builtins.def
index 219feeb..82c987d 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -646,13 +646,13 @@  DEF_LIB_BUILTIN        (BUILT_IN_MEMCHR, "memchr", BT_FN_PTR_CONST_PTR_INT_SIZE,
 DEF_LIB_BUILTIN        (BUILT_IN_MEMCMP, "memcmp", BT_FN_INT_CONST_PTR_CONST_PTR_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF)
 DEF_LIB_BUILTIN_CHKP   (BUILT_IN_MEMCPY, "memcpy", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
 DEF_LIB_BUILTIN_CHKP   (BUILT_IN_MEMMOVE, "memmove", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
-DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_MEMPCPY, "mempcpy", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
+DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_MEMPCPY, "mempcpy", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RETNONNULL_NOTHROW_LEAF)
 DEF_LIB_BUILTIN_CHKP   (BUILT_IN_MEMSET, "memset", BT_FN_PTR_PTR_INT_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_RINDEX, "rindex", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF)
-DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_STPCPY, "stpcpy", BT_FN_STRING_STRING_CONST_STRING, ATTR_NOTHROW_NONNULL_LEAF)
-DEF_EXT_LIB_BUILTIN    (BUILT_IN_STPNCPY, "stpncpy", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
+DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_STPCPY, "stpcpy", BT_FN_STRING_STRING_CONST_STRING, ATTR_RETNONNULL_NOTHROW_LEAF)
+DEF_EXT_LIB_BUILTIN    (BUILT_IN_STPNCPY, "stpncpy", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_RETNONNULL_NOTHROW_LEAF)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_STRCASECMP, "strcasecmp", BT_FN_INT_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
-DEF_LIB_BUILTIN_CHKP   (BUILT_IN_STRCAT, "strcat", BT_FN_STRING_STRING_CONST_STRING, ATTR_NOTHROW_NONNULL_LEAF)
+DEF_LIB_BUILTIN_CHKP   (BUILT_IN_STRCAT, "strcat", BT_FN_STRING_STRING_CONST_STRING, ATTR_RET1_NOTHROW_NONNULL_LEAF)
 DEF_LIB_BUILTIN_CHKP   (BUILT_IN_STRCHR, "strchr", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF)
 DEF_LIB_BUILTIN        (BUILT_IN_STRCMP, "strcmp", BT_FN_INT_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
 DEF_LIB_BUILTIN_CHKP   (BUILT_IN_STRCPY, "strcpy", BT_FN_STRING_STRING_CONST_STRING, ATTR_RET1_NOTHROW_NONNULL_LEAF)
@@ -661,9 +661,9 @@  DEF_EXT_LIB_BUILTIN    (BUILT_IN_STRDUP, "strdup", BT_FN_STRING_CONST_STRING, AT
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_STRNDUP, "strndup", BT_FN_STRING_CONST_STRING_SIZE, ATTR_MALLOC_NOTHROW_NONNULL_LEAF)
 DEF_LIB_BUILTIN_CHKP   (BUILT_IN_STRLEN, "strlen", BT_FN_SIZE_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_STRNCASECMP, "strncasecmp", BT_FN_INT_CONST_STRING_CONST_STRING_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF)
-DEF_LIB_BUILTIN        (BUILT_IN_STRNCAT, "strncat", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
+DEF_LIB_BUILTIN        (BUILT_IN_STRNCAT, "strncat", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
 DEF_LIB_BUILTIN        (BUILT_IN_STRNCMP, "strncmp", BT_FN_INT_CONST_STRING_CONST_STRING_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF)
-DEF_LIB_BUILTIN        (BUILT_IN_STRNCPY, "strncpy", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
+DEF_LIB_BUILTIN        (BUILT_IN_STRNCPY, "strncpy", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
 DEF_LIB_BUILTIN        (BUILT_IN_STRPBRK, "strpbrk", BT_FN_STRING_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
 DEF_LIB_BUILTIN        (BUILT_IN_STRRCHR, "strrchr", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF)
 DEF_LIB_BUILTIN        (BUILT_IN_STRSPN, "strspn", BT_FN_SIZE_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
@@ -904,14 +904,14 @@  DEF_BUILTIN_STUB (BUILT_IN_MEMCMP_EQ, "__builtin_memcmp_eq")
 DEF_GCC_BUILTIN	       (BUILT_IN_OBJECT_SIZE, "object_size", BT_FN_SIZE_CONST_PTR_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
 DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_MEMCPY_CHK, "__memcpy_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
 DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_MEMMOVE_CHK, "__memmove_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
-DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_MEMPCPY_CHK, "__mempcpy_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
-DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_MEMSET_CHK, "__memset_chk", BT_FN_PTR_PTR_INT_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
-DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_STPCPY_CHK, "__stpcpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
-DEF_EXT_LIB_BUILTIN    (BUILT_IN_STPNCPY_CHK, "__stpncpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
-DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_STRCAT_CHK, "__strcat_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
-DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_STRCPY_CHK, "__strcpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
-DEF_EXT_LIB_BUILTIN    (BUILT_IN_STRNCAT_CHK, "__strncat_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
-DEF_EXT_LIB_BUILTIN    (BUILT_IN_STRNCPY_CHK, "__strncpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
+DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_MEMPCPY_CHK, "__mempcpy_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_RETNONNULL_NOTHROW_LEAF)
+DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_MEMSET_CHK, "__memset_chk", BT_FN_PTR_PTR_INT_SIZE_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
+DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_STPCPY_CHK, "__stpcpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_RETNONNULL_NOTHROW_LEAF)
+DEF_EXT_LIB_BUILTIN    (BUILT_IN_STPNCPY_CHK, "__stpncpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_RETNONNULL_NOTHROW_LEAF)
+DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_STRCAT_CHK, "__strcat_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
+DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_STRCPY_CHK, "__strcpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
+DEF_EXT_LIB_BUILTIN    (BUILT_IN_STRNCAT_CHK, "__strncat_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
+DEF_EXT_LIB_BUILTIN    (BUILT_IN_STRNCPY_CHK, "__strncpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_SNPRINTF_CHK, "__snprintf_chk", BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_NOTHROW_5_6)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_SPRINTF_CHK, "__sprintf_chk", BT_FN_INT_STRING_INT_SIZE_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_NOTHROW_4_5)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_VSNPRINTF_CHK, "__vsnprintf_chk", BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_NOTHROW_5_0)
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..d908a39
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr78154.c
@@ -0,0 +1,43 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp-slim" } */
+
+void f(void *d, const void *s, __SIZE_TYPE__ n)
+{
+  void *t1 = __builtin_memcpy (d, s, n);
+  if (t1 == 0)
+    __builtin_abort ();
+
+  void *t2 = __builtin_memmove (d, s, n);
+  if (t2 == 0)
+    __builtin_abort ();
+
+  void *t3 = __builtin_memset (d, 0, n);
+  if (t3 == 0)
+    __builtin_abort ();
+
+  void *t4 = __builtin_strcpy (d, s);
+  if (t4 == 0)
+    __builtin_abort ();
+
+  void *t5 = __builtin_strncpy (d, s, n);
+  if (t5 == 0)
+    __builtin_abort ();
+
+  void *t6 = __builtin_strcat (d, s);
+  if (t6 == 0)
+    __builtin_abort ();
+
+  void *t7 = __builtin_strncat (d, s, n);
+  if (t7 == 0)
+    __builtin_abort ();
+
+  void *t8 = __builtin_stpcpy (d, s);
+  if (t8 == 0)
+    __builtin_abort ();
+
+  void *t9 = __builtin_stpncpy (d, s, n);
+  if (t9 == 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..7d9bdf5 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -1097,6 +1097,20 @@  gimple_stmt_nonzero_warnv_p (gimple *stmt, bool *strict_overflow_p)
 	    lookup_attribute ("returns_nonnull",
 			      TYPE_ATTRIBUTES (gimple_call_fntype (stmt))))
 	  return true;
+
+	unsigned rf = gimple_call_return_flags (as_a<gcall *> (stmt));
+	if (rf & ERF_RETURNS_ARG)
+	  {
+	    tree arg = gimple_call_arg (as_a<gcall *> (stmt), rf & ERF_RETURN_ARG_MASK);
+	    if (SSA_VAR_P (arg))
+	      {
+		value_range *vr = get_value_range (arg);
+		if ((vr && vr->type != VR_VARYING)
+		    || infer_nonnull_range_by_attribute (stmt, arg))
+		  return true;
+	      }
+	  }
+
 	return gimple_alloca_call_p (stmt);
       }
     default: