avoid -Wrestrict for null pointers (PR 85365)

Message ID 4e1d58ce-92a7-1ed1-31be-8b8fcbba9141@gmail.com
State New
Headers show
Series
  • avoid -Wrestrict for null pointers (PR 85365)
Related show

Commit Message

Martin Sebor April 13, 2018, 4:49 p.m.
PR 85365 is another example of a false positive caused by
the interaction between the instrumentation inserted by
sanitizers, jump threading, and a middle-end warning.
In this case, the warning is easy to avoid by suppressing
-Wrestrict for null pointers.  Although undefined, since
they do no point to an object, strictly speaking they do
not indicate an overlap, and so issuing a -Wrestrict
warning is not quite appropriate anyway.

Testing in progress.

Martin

Comments

Martin Sebor April 19, 2018, 4:05 p.m. | #1
Ping: https://gcc.gnu.org/ml/gcc-patches/2018-04/msg00676.html

Testing on x86_64-linux showed no regressions.

On 04/13/2018 10:49 AM, Martin Sebor wrote:
> PR 85365 is another example of a false positive caused by
> the interaction between the instrumentation inserted by
> sanitizers, jump threading, and a middle-end warning.
> In this case, the warning is easy to avoid by suppressing
> -Wrestrict for null pointers.  Although undefined, since
> they do no point to an object, strictly speaking they do
> not indicate an overlap, and so issuing a -Wrestrict
> warning is not quite appropriate anyway.
>
> Testing in progress.
>
> Martin
Richard Biener April 20, 2018, 6:41 a.m. | #2
On Thu, Apr 19, 2018 at 6:05 PM, Martin Sebor <msebor@gmail.com> wrote:
> Ping: https://gcc.gnu.org/ml/gcc-patches/2018-04/msg00676.html
>
> Testing on x86_64-linux showed no regressions.

OK.

Richard.

>
> On 04/13/2018 10:49 AM, Martin Sebor wrote:
>>
>> PR 85365 is another example of a false positive caused by
>> the interaction between the instrumentation inserted by
>> sanitizers, jump threading, and a middle-end warning.
>> In this case, the warning is easy to avoid by suppressing
>> -Wrestrict for null pointers.  Although undefined, since
>> they do no point to an object, strictly speaking they do
>> not indicate an overlap, and so issuing a -Wrestrict
>> warning is not quite appropriate anyway.
>>
>> Testing in progress.
>>
>> Martin
>
>

Patch

PR c/85365 -  -Wrestrict false positives with -fsanitize=undefined

gcc/ChangeLog:

	PR c/85365
	* gimple-fold.c (gimple_fold_builtin_strcpy): Suppress -Wrestrict
	for null pointers.
	(gimple_fold_builtin_stxcpy_chk): Same.
	* gimple-ssa-warn-restrict.c (check_bounds_or_overlap): Same.

gcc/testsuite/ChangeLog:

	PR c/85365
	* gcc.dg/Wrestrict-15.c: New test.

Index: gcc/gimple-fold.c
===================================================================
--- gcc/gimple-fold.c	(revision 259298)
+++ gcc/gimple-fold.c	(working copy)
@@ -1612,7 +1612,11 @@  gimple_fold_builtin_strcpy (gimple_stmt_iterator *
   /* If SRC and DEST are the same (and not volatile), return DEST.  */
   if (operand_equal_p (src, dest, 0))
     {
-      if (!gimple_no_warning_p (stmt))
+      /* Issue -Wrestrict unless the pointers are null (those do
+	 not point to objects and so do not indicate an overlap;
+	 such calls could be the result of sanitization and jump
+	 threading).  */
+      if (!integer_zerop (dest) && !gimple_no_warning_p (stmt))
 	{
 	  tree func = gimple_call_fndecl (stmt);
 
@@ -2593,7 +2597,11 @@  gimple_fold_builtin_stxcpy_chk (gimple_stmt_iterat
   /* If SRC and DEST are the same (and not volatile), return DEST.  */
   if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
     {
-      if (!gimple_no_warning_p (stmt))
+      /* Issue -Wrestrict unless the pointers are null (those do
+	 not point to objects and so do not indicate an overlap;
+	 such calls could be the result of sanitization and jump
+	 threading).  */
+      if (!integer_zerop (dest) && !gimple_no_warning_p (stmt))
 	{
 	  tree func = gimple_call_fndecl (stmt);
 
Index: gcc/gimple-ssa-warn-restrict.c
===================================================================
--- gcc/gimple-ssa-warn-restrict.c	(revision 259298)
+++ gcc/gimple-ssa-warn-restrict.c	(working copy)
@@ -1880,11 +1880,20 @@  check_bounds_or_overlap (gcall *call, tree dst, tr
 
   if (operand_equal_p (dst, src, 0))
     {
-      warning_at (loc, OPT_Wrestrict,
-		  "%G%qD source argument is the same as destination",
-		  call, func);
-      gimple_set_no_warning (call, true);
-      return false;
+      /* Issue -Wrestrict unless the pointers are null (those do
+	 not point to objects and so do not indicate an overlap;
+	 such calls could be the result of sanitization and jump
+	 threading).  */
+      if (!integer_zerop (dst) && !gimple_no_warning_p (call))
+	{
+	  warning_at (loc, OPT_Wrestrict,
+		      "%G%qD source argument is the same as destination",
+		      call, func);
+	  gimple_set_no_warning (call, true);
+	  return false;
+	}
+
+      return true;
     }
 
   /* Return false when overlap has been detected.  */
Index: gcc/testsuite/gcc.dg/Wrestrict-15.c
===================================================================
--- gcc/testsuite/gcc.dg/Wrestrict-15.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/Wrestrict-15.c	(working copy)
@@ -0,0 +1,38 @@ 
+/* PR 85365 - -Wrestrict false positives with -fsanitize=undefined
+   { dg-do compile }
+   { dg-options "-O2 -Wrestrict -fsanitize=undefined" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+char *strcpy (char *, const char *);
+char *strcat (char *, const char *);
+
+size_t strlen (char *);
+
+extern char a[], b[], d[];
+
+size_t t1 (char *g, int i)
+{
+  /* The following exercises the handling in gimple-fold.c.  */
+  strcpy (g + 4, i ? b : a);    /* { dg-bogus "\\\[-Wrestrict]" } */
+  return strlen (g + 4);
+}
+
+void t2 (char *g, int i)
+{
+  strcpy (g + 4, i ? b : a);    /* { dg-bogus "\\\[-Wrestrict]" } */
+  strcat (g + 4, d);
+}
+
+void t3 (char *g, int i)
+{
+  /* The following exercises the handling in gimple-ssa-warn-restrict.c.  */
+  strcat (g + 4, i ? b : a);    /* { dg-bogus "\\\[-Wrestrict]" } */
+  strcat (g + 4, d);
+}
+
+void t4 (char *p, char *q)
+{
+  strcpy (p, q);                /* { dg-bogus "\\\[-Wrestrict]" } */
+  strcat (p, q + 32);
+}