The r11-5622 change to -Wformat-overflow switched the warning
to using the maximm object size limit used by the other overflow
and out of bounds access warnings like -Wstringop-overflow.
That in turn exposed a subtle off-by-one mistake in the former
that was also reflected in a few tests, seen in ILP32 but not
in LP64.  I just committed the attached patch adjusts the tests
to correctly reflect the limit.  These mistakes would be easier
to avoid if if were possible to lower the max object size limit
from PTRDIFF_MAX - 1 to a value that's independent of the target
as in the following patch:

https://gcc.gnu.org/pipermail/gcc-patches/2020-November/559450.html

Martin
commit 0a7dc4b6440faa8cd57c630f1e394a719469c399
Author: Martin Sebor <mse...@redhat.com>
Date:   Wed Dec 2 11:29:11 2020 -0700

    Adjust test to avoid ILP32 failures after r11-5622 (PR middle-end/97373)
    
    gcc/testsuite/ChangeLog:
            * gcc.dg/tree-ssa/builtin-sprintf-warn-1.c: Adjust expected warnings
            to correctly reflect the maximum object size.
            * gcc.dg/tree-ssa/builtin-sprintf-warn-11.c: Same.
            * gcc.dg/tree-ssa/builtin-sprintf-warn-18.c: Same.

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-1.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-1.c
index a94d123b34c..3d238c4c3ed 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-1.c
@@ -112,17 +112,24 @@ void test_sprintf_c_const (void)
   T ( 3, "%1$c%2$c", '1', '2');
 
   /* Verify that a warning is issued for exceeding INT_MAX bytes and
-     not otherwise.  */
-  T (-1, "%*c",  INT_MAX - 1, '1');
-  T (-1, "%*c",  INT_MAX,     '1');
-  T (-1, "X%*c", INT_MAX - 1, '1');
-  T (-1, "X%*c", INT_MAX,     '1'); /* { dg-warning "directive output of \[0-9\]+ bytes causes result to exceed .INT_MAX." } */
-
-  T (-1, "%*c%*c", INT_MAX - 1, '1', INT_MAX - 1, '2'); /* { dg-warning "directive output of \[0-9\]+ bytes causes result to exceed .INT_MAX." } */
-
-  T (-1, "%*cX", INT_MAX - 2, '1');
-  T (-1, "%*cX", INT_MAX - 1, '1');
-  T (-1, "%*cX", INT_MAX,     '1'); /* { dg-warning "output of \[0-9\]+ bytes causes result to exceed .INT_MAX." } */
+     not otherwise.  In ILP32 where the maximum object size is INT_MAX - 1
+     bytes, the calls are diagnosed due to the overflow.  */
+  T (-1, "%*c",  INT_MAX - 2, '1');
+  T (-1, "%*c",  INT_MAX - 1, '1'); /* { dg-warning "writing a terminating nul past the end" "ilp32" { target ilp32 } } */
+  T (-1, "%*c",  INT_MAX,     '1'); /* { dg-warning "writing 2147483647 bytes into a region of size 2147483646" "il32" { target ilp32 } } */
+  T (-1, "X%*c", INT_MAX - 3, '1');
+  T (-1, "X%*c", INT_MAX - 1, '1'); /* { dg-warning "writing 2147483646 bytes into a region of size 2147483645" "ilp32" { target ilp32 } } */
+  T (-1, "X%*c", INT_MAX,     '1'); /* { dg-warning "directive output of \[0-9\]+ bytes causes result to exceed .INT_MAX." "lp64" { target lp64 } } */
+                                    /* { dg-warning "directive writing 2147483647 bytes into a region of size 2147483645." "lp32" { target ilp32 } .-1 } */
+
+  T (-1, "%*c%*c", INT_MAX - 1, '1', INT_MAX - 1, '2'); /* { dg-warning "directive output of \[0-9\]+ bytes causes result to exceed .INT_MAX." "lp64" { target lp64 } } */
+  /* { dg-warning "directive writing 2147483646 bytes into a region of size 0" "ilp32" { target ilp32 } .-1 } */
+
+  T (-1, "%*cX", INT_MAX - 3, '1');
+  T (-1, "%*cX", INT_MAX - 2, '1'); /* { dg-warning "writing a terminating nul past the end of the destination" "ilp32" { target ilp32} } */
+  T (-1, "%*cX", INT_MAX - 1, '1'); /* { dg-warning "'X' directive writing 1 byte into a region of size 0" "ilp32" { target ilp32 } } */
+  T (-1, "%*cX", INT_MAX,     '1'); /* { dg-warning "output of \[0-9\]+ bytes causes result to exceed .INT_MAX." "lp64" { target lp64 } } */
+  /* { dg-warning "directive writing 2147483647 bytes into a region of size 2147483646" "ilp32" { target ilp32 } .-1 } */
 }
 
 /* Verify that no warning is issued for calls that write into a flexible
@@ -287,9 +294,11 @@ void test_sprintf_chk_s_const (void)
 
   /* Verify that output in excess of INT_MAX bytes is diagnosed even
      when the size of the destination object is unknown.  */
-  T (-1, "%*s",  INT_MAX - 1, "");
-  T (-1, "%*s",  INT_MAX,     "");
-  T (-1, "X%*s", INT_MAX,     ""); /* { dg-warning "directive output of \[0-9\]+ bytes causes result to exceed .INT_MAX." } */
+  T (-1, "%*s",  INT_MAX - 2, "");
+  T (-1, "%*s",  INT_MAX - 1, ""); /* { dg-warning "writing a terminating nul past the end of the destination" "ilp32" { target ilp32 } } */
+  T (-1, "%*s",  INT_MAX,     ""); /* { dg-warning "directive writing 2147483647 bytes into a region of size 2147483646" "ilp32" { target ilp32 } } */
+  T (-1, "X%*s", INT_MAX,     ""); /* { dg-warning "directive output of \[0-9\]+ bytes causes result to exceed .INT_MAX." "lp64" { target lp64 } } */
+  /* { dg-warning "directive writing 2147483647 bytes into a region of size 2147483645" "ilp32" { target ilp32 } .-1 } */
 
   /* Multiple directives.  */
 
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-11.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-11.c
index 02072b55e86..22f286dc818 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-11.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-11.c
@@ -199,15 +199,21 @@ void test_narrow_string_with_width_and_precision (void)
 
   /* The two directives below combined convert to [INT_MAX, INT_MAX + 1].
      Since the lower end of the range doesn't exceed INT_MAX no warning
-     is expected.  */
+     is expected in LP64.  In ILP32 where the maximum object size is
+     INT_MAX - 1, the call is diagnosed.  */
+  T (-1, "%*.*s%*.*s",
+     IR (imax - 6, imax - 3), IR (1, 2), SR (x, y),
+     IR (       4,        6), IR (3, 4), SR (x, y));
   T (-1, "%*.*s%*.*s",
      IR (imax - 5, imax - 3), IR (1, 2), SR (x, y),
      IR (       5,        6), IR (3, 4), SR (x, y));
+  /* { dg-warning "directive writing between 5 and 6 bytes into a region of size between 2 and 4" "ilp32" { target ilp32 } .-3 } */
 
   /* The three directives below (the two %s plus the space in between)
      combined convert to [INT_MAX + 1, INT_MAX + 2].  Since the lower
      end of the range exceeds INT_MAX a warning is expected.  */
-  T (-1, "%*.*s %*.*s",                                     /* { dg-warning "INT_MAX" } */
+  T (-1, "%*.*s %*.*s",                                     /* { dg-warning "INT_MAX" "lp64" { target lp64 } } */
+     /* { dg-warning "directive writing between 5 and 6 bytes into a region of size between 1 and 3" "ilp32" { target ilp32 } .-1 } */
      IR (imax - 5, imax - 3), IR (1, 2), SR (x, y),
      IR (       5,        6), IR (3, 4), SR (x, y));
 
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-18.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-18.c
index 6a18f1776a7..d30775dc62d 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-18.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-18.c
@@ -118,9 +118,9 @@ void test_width_and_precision_out_of_range (char *d)
   /* The range here happens to be a property of the compiler, not
      one of the target.  */
   T ("%9223372036854775808i", 0);    /* { dg-warning "width out of range" "first" } */
-  /* { dg-warning "exceeds .INT_MAX." "second" { target *-*-* } .-1 } */
+  /* { dg-warning "directive writing \\d+ bytes into a region of size \\d+" "second" { target *-*-* } .-1 } */
   T ("%.9223372036854775808i", 0);   /* { dg-warning "precision out of range" "first" } */
-  /* { dg-warning "exceeds .INT_MAX." "second" { target *-*-* } .-1 } */
+  /* { dg-warning "directive writing \\d+ bytes into a region of size \\d+" "second" { target *-*-* } .-1 } */
 
   /* The following is diagnosed by -Wformat (disabled here).  */
   /* T ("%9223372036854775808$i", 0); */

Reply via email to