[committed] avoid bogus -Wstringop-overflow with VLA (PR 100571)

Message ID bfdb1f5a-01e0-4a9b-ec99-a2d1df82c324@gmail.com
State New
Headers show
Series
  • [committed] avoid bogus -Wstringop-overflow with VLA (PR 100571)
Related show

Commit Message

H.J. Lu via Gcc-patches May 12, 2021, 9:56 p.m.
A recent Glibc enhancement to add attribute access to a bunch of
APIs has triggered a couple of false positives in the test suite
when using GCC 10.  The problem has been fixed on trunk as part
of a bigger commit that's not suitable for backporting (it adds
new warnings).  The attached change fixes just the narrow problem
that impacts Glibc.  I have committed it to 10-branch in r10-9819.

Martin

Patch

commit 7b6740756c9ca64dd01097b629c19e26d3d6a504
Author: Martin Sebor <msebor@redhat.com>
Date:   Wed May 12 15:45:44 2021 -0600

    PR middle-end/100571 - bogus -Wstringop-overflow with VLA of elements larger than byte
    
    gcc/ChangeLog:
            PR middle-end/100571
            * gcc/calls.c (maybe_warn_rdwr_sizes): Clear object size if it can't
            be determined.
    
    gcc/testsuite/ChangeLog:
            PR middle-end/100571
            * gcc.dg/Wstringop-overflow-67.c: New test.

diff --git a/gcc/calls.c b/gcc/calls.c
index 26894342c21..45c137cee1e 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -2112,6 +2112,11 @@  maybe_warn_rdwr_sizes (rdwr_map *rwm, tree fndecl, tree fntype, tree exp)
 	}
       else
 	{
+	  /* If the size cannot be determined clear it to keep it from
+	     being taken as real (and excessive).  */
+	  if (objsize && integer_all_onesp (objsize))
+	    objsize = NULL_TREE;
+
 	  /* For read-only and read-write attributes also set the source
 	     size.  */
 	  srcsize = objsize;
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-67.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-67.c
new file mode 100644
index 00000000000..7b8f3f014c6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-67.c
@@ -0,0 +1,92 @@ 
+/* PR middle-end/100571 - bogus -Wstringop-overflow with VLA of elements
+   larger than byte
+   { dg-do compile }
+   { dg-options "-O2 -Wall" } */
+
+__attribute__ ((access (read_only, 1, 2))) void fro (int *, int);
+__attribute__ ((access (write_only, 1, 2))) void fwo (int *, int);
+__attribute__ ((access (read_write, 1, 2))) void frw (int *, int);
+
+extern __SIZE_TYPE__ n;
+
+void alloca_ro (void)
+{
+  int *a = __builtin_alloca (n * sizeof *a);
+  a[0] = 0;
+  fro (a, n);
+}
+
+void alloca_wo (void)
+{
+  int *a = __builtin_alloca (n * sizeof *a);
+  fwo (a, n);
+}
+
+void alloca_rw (void)
+{
+  int *a = __builtin_alloca (n * sizeof *a);
+  a[0] = 0;
+  frw (a, n);
+}
+
+
+void calloc_ro (void)
+{
+  int *a = __builtin_calloc (n, sizeof *a);
+  fro (a, n);
+}
+
+void calloc_wo (void)
+{
+  int *a = __builtin_calloc (n, sizeof *a);
+  fwo (a, n);
+}
+
+void calloc_rw (void)
+{
+  int *a = __builtin_calloc (n, sizeof *a);
+  a[0] = 0;
+  frw (a, n);
+}
+
+
+void malloc_ro (void)
+{
+  int *a = __builtin_malloc (n * sizeof *a);
+  a[0] = 0;
+  fro (a, n);
+}
+
+void malloc_wo (void)
+{
+  int *a = __builtin_malloc (n * sizeof *a);
+  fwo (a, n);
+}
+
+void malloc_rw (void)
+{
+  int *a = __builtin_malloc (n * sizeof *a);
+  a[0] = 0;
+  frw (a, n);
+}
+
+
+void vla_ro (void)
+{
+  int a[n];
+  a[0] = 0;
+  fro (a, n);
+}
+
+void vla_wo (void)
+{
+  int a[n];
+  fwo (a, n);
+}
+
+void vla_rw (void)
+{
+  int a[n];
+  a[0] = 0;
+  frw (a, n);
+}