Add tests for PR92942 - missing -Wstringop-overflow for allocations with a negative...
authorMartin Sebor <msebor@redhat.com>
Tue, 27 Oct 2020 14:31:53 +0000 (08:31 -0600)
committerMartin Sebor <msebor@redhat.com>
Tue, 27 Oct 2020 14:31:53 +0000 (08:31 -0600)
gcc/testsuite/ChangeLog:

PR middle-end/92942
* gcc.dg/Wstringop-overflow-56.c: New test.
* gcc.dg/Wstringop-overflow-57.c: Same.

gcc/testsuite/gcc.dg/Wstringop-overflow-56.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/Wstringop-overflow-57.c [new file with mode: 0644]

diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-56.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-56.c
new file mode 100644 (file)
index 0000000..b3e598c
--- /dev/null
@@ -0,0 +1,163 @@
+/* PR middle-end/92942 - missing -Wstringop-overflow for allocations with
+   a negative lower bound size
+   { dg-do compile }
+   { dg-options "-O2 -Wall" } */
+
+#define SIZE_MAX        __SIZE_MAX__
+#define UINT8_MAX       __UINT8_MAX__
+#define UINT16_MAX      __UINT16_MAX__
+
+typedef __SIZE_TYPE__   size_t;
+typedef __UINT8_TYPE__  uint8_t;
+typedef __UINT16_TYPE__ uint16_t;
+
+void* usr_alloc1 (size_t) __attribute__ ((alloc_size (1)));
+void* usr_alloc2 (size_t, size_t)  __attribute__ ((alloc_size (1, 2)));
+
+void* malloc (size_t);
+void* memcpy (void*, const void*, size_t);
+void* memset (void*, int, size_t);
+char* strcpy (char*, const char*);
+
+void sink (void*);
+
+void malloc_uint_range_strcpy (unsigned n)
+{
+  void *p = malloc (5 < n ? 5 : n);
+
+  strcpy (p, "01234");              // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (p);
+
+  strcpy (p, "0123");
+  sink (p);
+}
+
+void malloc_uint16_anti_range_memset (uint16_t n)
+{
+  if (5 <= n && n <= 9) return;
+  void *p = malloc (n);
+
+  if (UINT16_MAX < SIZE_MAX)
+    {
+      size_t sz = (uint16_t)-1 + (size_t)1;
+      memset (p, 0, sz);            // { dg-warning "\\\[-Wstringop-overflow" }
+      sink (p);
+    }
+
+  memset (p, 0, 1);
+  sink (p);
+  memset (p, 0, 5);
+  sink (p);
+  memset (p, 0, 6);
+  sink (p);
+  memset (p, 0, UINT16_MAX - 1);
+  sink (p);
+  memset (p, 0, UINT16_MAX);
+  sink (p);
+}
+
+void malloc_int_strcpy (int n)
+{
+  void *p = malloc (7 < n ? 7 : n);
+
+  strcpy (p, "0123456");            // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (p);
+
+  strcpy (p, "012345");
+  sink (p);
+}
+
+void vla_int_strcpy (int n)
+{
+  char a[9 < n ? 9 : n];
+
+  strcpy (a, "012345678");          // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (a);
+
+  strcpy (a, "01234567");
+  sink (a);
+}
+
+void usr_alloc1_int_strcpy (int n)
+{
+  void *p = usr_alloc1 (7 < n ? 7 : n);
+
+  strcpy (p, "0123456");            // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (p);
+
+  strcpy (p, "012345");
+  sink (p);
+}
+
+void usr_alloc2_cst_ir_strcpy (int n)
+{
+  void *p = usr_alloc2 (1, 5 < n ? 5 : n);
+
+  strcpy (p, "01234");              // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (p);
+
+  strcpy (p, "0123");
+  sink (p);
+}
+
+void usr_alloc2_ir_ir_strcpy (int m, int n)
+{
+  void *p = usr_alloc2 (3 < n ? 3 : n, 5 < n ? 5 : n);
+
+  strcpy (p, "0123456789abcde");    // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (p);
+
+  strcpy (p, "0123456789abcd");
+  sink (p);
+}
+
+void usr_alloc2_uint8_memset (uint8_t m, uint8_t n)
+{
+  if (3 <= m && m <= 7) return;
+  if (5 <= n && n <= 9) return;
+  void *p = usr_alloc2 (m, n);
+
+  size_t sz = UINT8_MAX * UINT8_MAX + 1;
+  memset (p, 0, sz);               // { dg-warning "\\\[-Wstringop-overflow" "" { xfail *-*-* } }
+                                   // { dg-warning "\\\[-Warray-bounds" "pr?????" { target *-*-* } .-1 }
+  sink (p);
+
+  memset (p, 0, sz - 1);
+  sink (p);
+  memset (p, 0, 64);
+  sink (p);
+  memset (p, 0, 63);
+  sink (p);
+  memset (p, 0, 16);
+  sink (p);
+  memset (p, 0, 15);
+  sink (p);
+  memset (p, 0, 14);
+  sink (p);
+  memset (p, 0, 3);
+  sink (p);
+}
+
+
+
+void malloc_int_memset (int n)
+{
+  void *p = malloc (11 < n ? 11 : n);
+
+  memset (p, 0, 12);                // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (p);
+
+  memset (p, 0, 11);
+  sink (p);
+}
+
+void vla_int_memset (int n)
+{
+  char a[13 < n ? 13 : n];
+
+  memset (a, 0, 14);                // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (a);
+
+  memset (a, 0, 13);
+  sink (a);
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-57.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-57.c
new file mode 100644 (file)
index 0000000..173aa16
--- /dev/null
@@ -0,0 +1,91 @@
+/* Verify that an anti-range ~[A, B] with small positive A and B
+   is handled correctly and doesn't trigger warnings.
+   { dg-do compile }
+   { dg-options "-O2 -Wall" } */
+
+typedef __typeof__ (sizeof 0) size_t;
+
+int f (void*, size_t);
+int g (void*);
+
+// Test case distilled from gcc/cp/semantics.c
+
+int omp_reduction_id (int i, int j, const char *mm)
+{
+  const char *p = 0;
+  const char *m = 0;
+
+  switch (i)
+    {
+    case 1:
+      p = "min";
+      break;
+    case 2:
+      p = "max";
+      break;
+    default:
+      break;
+    }
+
+  if (j)
+    m = mm;
+
+  const char prefix[] = "omp declare reduction ";
+  size_t lenp = sizeof (prefix);
+
+  if (__builtin_strncmp (p, prefix, lenp - 1) == 0)
+    lenp = 1;
+
+  size_t len = __builtin_strlen (p);
+  size_t lenm = m ? __builtin_strlen (m) + 1 : 0;
+  char *name = ((char *) __builtin_alloca(lenp + len + lenm));
+
+  if (lenp > 1)
+    __builtin_memcpy (name, prefix, lenp - 1);
+
+  __builtin_memcpy (name + lenp - 1, p, len + 1);
+  if (m)
+    {
+      name[lenp + len - 1] = '~';
+      __builtin_memcpy (name + lenp + len, m, lenm);
+    }
+  return (__builtin_constant_p (name)
+         ? f (name, __builtin_strlen (name)) : g (name));
+}
+
+// Test case derived from gcc/d/dmd/root/filename.c.
+
+const char *ext (const char *str)
+{
+  size_t len = __builtin_strlen(str);
+
+  const char *e = str + len;
+  for (;;)
+    {
+      switch (*e)
+        {
+       case '.': return e + 1;
+       case '/': break;
+       default:
+         if (e == str)
+           break;
+         e--;
+         continue;
+        }
+      return 0;
+    }
+}
+
+const char *removeExt (const char *str)
+{
+  const char *e = ext (str);
+  if (e)
+    {
+      size_t len = (e - str) - 1;
+      char *n = (char *)__builtin_malloc (len + 1);
+      __builtin_memcpy(n, str, len);
+      n[len] = 0;
+      return n;
+    }
+  return 0;
+}