PR tree-optimization/89644 - False-positive -Warray-bounds diagnostic on strncpy
authorMartin Sebor <msebor@redhat.com>
Tue, 19 Mar 2019 17:45:34 +0000 (17:45 +0000)
committerMartin Sebor <msebor@gcc.gnu.org>
Tue, 19 Mar 2019 17:45:34 +0000 (11:45 -0600)
gcc/ChangeLog:

PR tree-optimization/89644
* tree-ssa-strlen.c (handle_builtin_stxncpy): Consider unterminated
arrays in determining sequence sizes in strncpy and stpncpy.

gcc/testsuite/ChangeLog:

PR tree-optimization/89644
* gcc.dg/Wstringop-truncation-8.c: New test.

From-SVN: r269807

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/Wstringop-truncation-8.c [new file with mode: 0644]
gcc/tree-ssa-strlen.c

index 750d5e67cfd94696e332d29e778db5670d4121e8..fe1f0640e7f8b041220569e14baffbf90a66502f 100644 (file)
@@ -1,3 +1,9 @@
+2019-03-19  Martin Sebor  <msebor@redhat.com>
+
+       PR tree-optimization/89644
+       * tree-ssa-strlen.c (handle_builtin_stxncpy): Consider unterminated
+       arrays in determining sequence sizes in strncpy and stpncpy.
+
 2019-03-19  Martin Liska  <mliska@suse.cz>
 
        PR middle-end/89737
index 86cc80b3d3783f57da264f2a6fbf40b854064c93..cf01b2fea19eafae2bfb7f9329f31e3fcc381dbf 100644 (file)
@@ -1,3 +1,8 @@
+2019-03-19  Martin Sebor  <msebor@redhat.com>
+
+       PR tree-optimization/89644
+       * gcc.dg/Wstringop-truncation-8.c: New test.
+
 2019-03-19  Martin Liska  <mliska@suse.cz>
 
        PR middle-end/89737
diff --git a/gcc/testsuite/gcc.dg/Wstringop-truncation-8.c b/gcc/testsuite/gcc.dg/Wstringop-truncation-8.c
new file mode 100644 (file)
index 0000000..1745da5
--- /dev/null
@@ -0,0 +1,94 @@
+/* PR tree-optimization/89644 - False-positive -Warray-bounds diagnostic
+   on strncpy
+   { dg-do compile }
+   { dg-options "-O2 -Wall -ftrack-macro-expansion=0" }  */
+
+#define NONSTR __attribute__ ((nonstring))
+
+typedef __SIZE_TYPE__ size_t;
+
+size_t strlen (const char*);
+extern char* stpncpy (char*, const char*, size_t);
+extern char* strncpy (char*, const char*, size_t);
+
+void sink (char*, ...);
+
+char f0 (char *s)
+{
+  char a[6] NONSTR = { 1, 2, 3, 4, 5, 6 };
+  if (*s)
+    strncpy (a, s, sizeof a);       /* { dg-bogus "\\\[-Warray-bounds" } */
+  return a[0];
+}
+
+void f1 (char *s)
+{
+  char a[6] NONSTR = { 1, 2, 3, 4, 5, 6 };
+  if (*s)
+    strncpy (a, s, sizeof a);       /* { dg-bogus "\\\[-Warray-bounds" } */
+  sink (a);
+}
+
+char f2 (void)
+{
+  char a[6] NONSTR = { 1, 2, 3, 4, 5, 6 };
+  char b[6] NONSTR = { 6, 5, 4, 3, 2, 1 };
+  strncpy (a, b + 1, 5);            /* { dg-bogus "\\\[-Warray-bounds" } */
+  return a[0];
+}
+
+void f3 (void)
+{
+  char a[6] NONSTR = { 1, 2, 3, 4, 5, 6 };
+  char b[6] NONSTR = { 6, 5, 4, 3, 2, 1 };
+  strncpy (a, b + 2, 4);            /* { dg-bogus "\\\[-Warray-bounds" } */
+  sink (a);
+}
+
+void f4 (NONSTR char *d)
+{
+  char b[6] NONSTR = { 6, 5, 4, 3, 2, 1 };
+  strncpy (d, b + 3, 3);            /* { dg-bogus "\\\[-Warray-bounds" } */
+  sink (d);
+}
+
+
+char g0 (char *s)
+{
+  char a[6] NONSTR = { 1, 2, 3, 4, 5, 6 };
+  if (*s)
+    stpncpy (a, s, sizeof a);       /* { dg-bogus "\\\[-Warray-bounds" } */
+  return a[0];
+}
+
+void g1 (char *s)
+{
+  char a[6] NONSTR = { 1, 2, 3, 4, 5, 6 };
+  char *p = 0;
+  if (*s)
+    p = stpncpy (a, s, sizeof a);   /* { dg-bogus "\\\[-Warray-bounds" } */
+  sink (a, p);
+}
+
+char g2 (void)
+{
+  char a[6] NONSTR = { 1, 2, 3, 4, 5, 6 };
+  char b[6] NONSTR = { 6, 5, 4, 3, 2, 1 };
+  stpncpy (a, b + 1, 5);            /* { dg-bogus "\\\[-Warray-bounds" } */
+  return a[0];
+}
+
+void g3 (void)
+{
+  char a[6] NONSTR = { 1, 2, 3, 4, 5, 6 };
+  char b[6] NONSTR = { 6, 5, 4, 3, 2, 1 };
+  char *p = stpncpy (a, b + 2, 4);  /* { dg-bogus "\\\[-Warray-bounds" } */
+  sink (a, p);
+}
+
+void g4 (NONSTR char *d)
+{
+  char b[6] NONSTR = { 6, 5, 4, 3, 2, 1 };
+  char *p = stpncpy (d, b + 3, 3);  /* { dg-bogus "\\\[-Warray-bounds" } */
+  sink (d, p);
+}
index 1eaed666ef2bda96a74c4537931a8afa0a160051..cf0f70d9d7f5035e239d730ee78fa6ba64b8d474 100644 (file)
@@ -2206,13 +2206,21 @@ handle_builtin_stxncpy (built_in_function, gimple_stmt_iterator *gsi)
   int didx = get_stridx (dst);
   if (strinfo *sidst = didx > 0 ? get_strinfo (didx) : NULL)
     {
-      /* Compute the size of the destination string including the NUL.  */
+      /* Compute the size of the destination string including the nul
+        if it is known to be nul-terminated.  */
       if (sidst->nonzero_chars)
        {
-         tree type = TREE_TYPE (sidst->nonzero_chars);
-         dstsize = fold_build2 (PLUS_EXPR, type, sidst->nonzero_chars,
-                                build_int_cst (type, 1));
+         if (sidst->endptr)
+           {
+             /* String is known to be nul-terminated.  */
+             tree type = TREE_TYPE (sidst->nonzero_chars);
+             dstsize = fold_build2 (PLUS_EXPR, type, sidst->nonzero_chars,
+                                    build_int_cst (type, 1));
+           }
+         else
+           dstsize = sidst->nonzero_chars;
        }
+
       dst = sidst->ptr;
     }
 
@@ -2224,12 +2232,18 @@ handle_builtin_stxncpy (built_in_function, gimple_stmt_iterator *gsi)
         over the terminating nul so SISRC->DONT_INVALIDATE must be left
         clear.  */
 
-      /* Compute the size of the source string including the NUL.  */
+      /* Compute the size of the source string including the terminating
+        nul if its known to be nul-terminated.  */
       if (sisrc->nonzero_chars)
        {
-         tree type = TREE_TYPE (sisrc->nonzero_chars);
-         srcsize = fold_build2 (PLUS_EXPR, type, sisrc->nonzero_chars,
-                                build_int_cst (type, 1));
+         if (sisrc->endptr)
+           {
+             tree type = TREE_TYPE (sisrc->nonzero_chars);
+             srcsize = fold_build2 (PLUS_EXPR, type, sisrc->nonzero_chars,
+                                    build_int_cst (type, 1));
+           }
+         else
+           srcsize = sisrc->nonzero_chars;
        }
 
        src = sisrc->ptr;