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] suppress -Wstringop-overflow when no-warning is set (PR 83508)


To avoid issuing duplicate warnings for the same function call
in the source code the -Wrestrict warning code makes sure
the no-warning bit is propagated between trees and GIMPLE and
tested before issuing a warning.  But the warning also detects
some of the same problems as -Wstringop-overflow, and that
warning was not updated to pay attention to the no-warning bit.
This can in turn lead to two warnings for what boils down to
the same bug.  The warnings can be confusing when the first
one references the function as it appears in the source code
and the second one the one it was transformed to by GCC after
the first warning was issued.

The attached patch corrects this oversight by having
the buffer overflow checker test the no-warning bit and skip
issuing a diagnostic.  (The function that does the overflow
checking still runs so that it can continue to indicate to its
callers whether an overflow has been detected.)

Bootstrap on x86_64-linux in progress.

Martin
PR other/83508 - c-c++-common/Wrestrict.c fails since r255836

gcc/testsuite/ChangeLog:

	PR other/83508
	* gcc.dg/Wstringop-overflow-2.c: New test.

gcc/ChangeLog:

	PR other/83508
	* builtins.c (check_access): Avoid warning when the no-warning bit
	is set.

diff --git a/gcc/builtins.c b/gcc/builtins.c
index 1d6e69d..a1b6a4e 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -3150,6 +3150,9 @@ check_access (tree exp, tree, tree, tree dstwrite,
 	      || (tree_fits_uhwi_p (dstwrite)
 		  && tree_int_cst_lt (dstwrite, range[0]))))
 	{
+	  if (TREE_NO_WARNING (exp))
+	    return false;
+
 	  location_t loc = tree_nonartificial_location (exp);
 	  loc = expansion_point_location_if_in_system_header (loc);
 
@@ -3209,6 +3212,9 @@ check_access (tree exp, tree, tree, tree dstwrite,
 
 	  if (tree_int_cst_lt (maxobjsize, range[0]))
 	    {
+	      if (TREE_NO_WARNING (exp))
+		return false;
+
 	      /* Warn about crazy big sizes first since that's more
 		 likely to be meaningful than saying that the bound
 		 is greater than the object size if both are big.  */
@@ -3230,6 +3236,9 @@ check_access (tree exp, tree, tree, tree dstwrite,
 
 	  if (dstsize != maxobjsize && tree_int_cst_lt (dstsize, range[0]))
 	    {
+	      if (TREE_NO_WARNING (exp))
+		return false;
+
 	      if (tree_int_cst_equal (range[0], range[1]))
 		warning_at (loc, opt,
 			    "%K%qD specified bound %E "
@@ -3253,6 +3262,9 @@ check_access (tree exp, tree, tree, tree dstwrite,
       && dstwrite && range[0]
       && tree_int_cst_lt (slen, range[0]))
     {
+      if (TREE_NO_WARNING (exp))
+	return false;
+
       location_t loc = tree_nonartificial_location (exp);
 
       if (tree_int_cst_equal (range[0], range[1]))
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-2.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-2.c
new file mode 100644
index 0000000..6e3e2ca
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-2.c
@@ -0,0 +1,30 @@
+/* PR tree-optimization/83508 - c-c++-common/Wrestrict.c fails since r255836
+   Test to verify that only one of -Wrestrict and -Wstringop-overflow is
+   issued for a problem where either would be appropriate.
+   { dg-do compile }
+   { dg-options "-O2 -Wrestrict -Wstringop-overflow" } */
+
+#define DIFF_MAX __PTRDIFF_MAX__
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+typedef __SIZE_TYPE__ size_t;
+
+void sink (void*);
+
+void f (ptrdiff_t i, size_t n)
+{
+  if (i < DIFF_MAX - 2 || DIFF_MAX - 1 > i)
+    i = DIFF_MAX - 2;
+
+  if (n < 4 || 5 < n)
+    n = 4;
+
+  char a[8] = "012";
+
+  /* The following could very well be diagnosed by -Wstringop-overflow
+     instead but there's no way to verify that only one of the two
+     warnings is issued and the choice of -Wrestrict simply reflects
+     the fact that -Wrestrict runs before -Wstringop-overflow.  */
+  __builtin_strncpy (a + i, a, n);   /* { dg-warning "\\\[-Wrestrict]" } */
+  sink (a);
+}

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