re PR c/87028 (false positive -Wstringop-truncation strncpy with global variable...
authorJeff Law <law@gcc.gnu.org>
Wed, 5 Dec 2018 23:10:08 +0000 (16:10 -0700)
committerJeff Law <law@gcc.gnu.org>
Wed, 5 Dec 2018 23:10:08 +0000 (16:10 -0700)
PR c/87028
* calls.c (get_attr_nonstring_decl): Avoid setting *REF to
SSA_NAME_VAR.
* gcc/gimple-low.c (lower_stmt): Fold builtin calls here.
* gimplify (maybe_fold_stmt): Avoid folding builtin calls.

PR c/87028
* c-c++-common/Wstringop-truncation.c: Remove xfails.
* gcc.dg/Wstringop-truncation-5.c: New test.
* gcc.dg/strcmpopt_1.c: Adjust.
* gcc.dg/tree-ssa/pr79697.c: Same.

From-SVN: r266833

gcc/ChangeLog
gcc/calls.c
gcc/gimple-low.c
gcc/gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/Wstringop-truncation.c
gcc/testsuite/gcc.dg/Wstringop-truncation-5.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/fold-bcopy.c
gcc/testsuite/gcc.dg/strcmpopt_1.c
gcc/testsuite/gcc.dg/tree-ssa/pr79697.c

index 533f1a07b2a637e64d8b4e6850e8ddead2a3ce9a..639f5cfd9849048f8c6722d786d4814550c0017b 100644 (file)
@@ -1,3 +1,12 @@
+2018-12-05  Richard Biener  <rguenther@suse.de>
+           Martin Sebor <msebor@redhat.com>
+
+       PR c/87028
+       * calls.c (get_attr_nonstring_decl): Avoid setting *REF to
+       SSA_NAME_VAR.
+       * gcc/gimple-low.c (lower_stmt): Fold builtin calls here.
+       * gimplify (maybe_fold_stmt): Avoid folding builtin calls.
+
 2018-12-05  Iain Sandoe  <iain@sandoe.co.uk>
 
        * configure.ac (gcc_cv_otool): Set.
index 8978d3b42fdeaa19aa5162d15c963d09ceed80c9..98c6377d78f6f21359785db971316dbb3fe51f2a 100644 (file)
@@ -1503,6 +1503,7 @@ tree
 get_attr_nonstring_decl (tree expr, tree *ref)
 {
   tree decl = expr;
+  tree var = NULL_TREE;
   if (TREE_CODE (decl) == SSA_NAME)
     {
       gimple *def = SSA_NAME_DEF_STMT (decl);
@@ -1515,17 +1516,25 @@ get_attr_nonstring_decl (tree expr, tree *ref)
              || code == VAR_DECL)
            decl = gimple_assign_rhs1 (def);
        }
-      else if (tree var = SSA_NAME_VAR (decl))
-       decl = var;
+      else
+       var = SSA_NAME_VAR (decl);
     }
 
   if (TREE_CODE (decl) == ADDR_EXPR)
     decl = TREE_OPERAND (decl, 0);
 
+  /* To simplify calling code, store the referenced DECL regardless of
+     the attribute determined below, but avoid storing the SSA_NAME_VAR
+     obtained above (it's not useful for dataflow purposes).  */
   if (ref)
     *ref = decl;
 
-  if (TREE_CODE (decl) == ARRAY_REF)
+  /* Use the SSA_NAME_VAR that was determined above to see if it's
+     declared nonstring.  Otherwise drill down into the referenced
+     DECL.  */
+  if (var)
+    decl = var;
+  else if (TREE_CODE (decl) == ARRAY_REF)
     decl = TREE_OPERAND (decl, 0);
   else if (TREE_CODE (decl) == COMPONENT_REF)
     decl = TREE_OPERAND (decl, 1);
index c3777a1e761736ef805cc37f1d753ba4b4f53332..b00e14f6554b4d591acc0dde07cd20c0d62951ec 100644 (file)
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-low.h"
 #include "predict.h"
 #include "gimple-predict.h"
+#include "gimple-fold.h"
 
 /* The differences between High GIMPLE and Low GIMPLE are the
    following:
@@ -378,6 +379,12 @@ lower_stmt (gimple_stmt_iterator *gsi, struct lower_data *data)
            gsi_next (gsi);
            return;
          }
+
+       /* We delay folding of built calls from gimplification to
+          here so the IL is in consistent state for the diagnostic
+          machineries job.  */
+       if (gimple_call_builtin_p (stmt))
+         fold_stmt (gsi);
       }
       break;
 
index 40fbaa2c523177031e50993b5575f821cf519227..d96ee43e7deedc2ecc546641c9b49f5f9d96f4ab 100644 (file)
@@ -3192,6 +3192,10 @@ maybe_fold_stmt (gimple_stmt_iterator *gsi)
       return false;
     else if ((ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
       return false;
+  /* Delay folding of builtins until the IL is in consistent state
+     so the diagnostic machinery can do a better job.  */
+  if (gimple_call_builtin_p (gsi_stmt (*gsi)))
+    return false;
   return fold_stmt (gsi);
 }
 
index 77dbe743406b66c8356584d9e8d3a25effcc746f..8bed4b455e0414ddaf930235330d238c7e395477 100644 (file)
@@ -1,3 +1,11 @@
+2018-12-05  Martin Sebor  <msebor@redhat.com>
+
+       PR c/87028
+       * c-c++-common/Wstringop-truncation.c: Remove xfails.
+       * gcc.dg/Wstringop-truncation-5.c: New test.
+       * gcc.dg/strcmpopt_1.c: Adjust.
+       * gcc.dg/tree-ssa/pr79697.c: Same.
+
 2018-12-05  Richard Sandiford  <richard.sandiford@arm.com>
 
        PR tree-optimization/88064
index e78e85ec8702f7186763de4a525597733363be65..b85711d6b3f399a476a7ae0a9cce9c03b90fd1e2 100644 (file)
@@ -329,9 +329,8 @@ void test_strncpy_array (Dest *pd, int i, const char* s)
      of the array to NUL is not diagnosed.  */
   {
     /* This might be better written using memcpy() but it's safe so
-       it probably shouldn't be diagnosed.  It currently triggers
-       a warning because of bug 81704.  */
-    strncpy (dst7, "0123456", sizeof dst7);   /* { dg-bogus "\\\[-Wstringop-truncation]" "bug 81704" { xfail *-*-* } } */
+       it shouldn't be diagnosed.  */
+    strncpy (dst7, "0123456", sizeof dst7);   /* { dg-bogus "\\\[-Wstringop-truncation]" } */
     dst7[sizeof dst7 - 1] = '\0';
     sink (dst7);
   }
@@ -350,7 +349,7 @@ void test_strncpy_array (Dest *pd, int i, const char* s)
   }
 
   {
-    strncpy (pd->a5, "01234", sizeof pd->a5);   /* { dg-bogus "\\\[-Wstringop-truncation]" "bug 81704" { xfail *-*-* } } */
+    strncpy (pd->a5, "01234", sizeof pd->a5);   /* { dg-bogus "\\\[-Wstringop-truncation]" } */
     pd->a5[sizeof pd->a5 - 1] = '\0';
     sink (pd);
   }
diff --git a/gcc/testsuite/gcc.dg/Wstringop-truncation-5.c b/gcc/testsuite/gcc.dg/Wstringop-truncation-5.c
new file mode 100644 (file)
index 0000000..dbb5e1f
--- /dev/null
@@ -0,0 +1,128 @@
+/* PR tree-optimization/87028 - false positive -Wstringop-truncation
+   strncpy with global variable source string
+   { dg-do compile }
+   { dg-options "-O2 -Wstringop-truncation" } */
+
+char *strncpy (char *, const char *, __SIZE_TYPE__);
+
+#define STR   "1234567890"
+
+struct S
+{
+  char a[5], b[5];
+};
+
+const char arr[] = STR;
+const char* const ptr = STR;
+
+const char arr2[][10] = { "123", STR };
+
+void test_literal (struct S *s)
+{
+  strncpy (s->a, STR, sizeof s->a - 1);     /* { dg-bogus "\\\[-Wstringop-truncation]" } */
+  s->a[sizeof s->a - 1] = '\0';
+}
+
+void test_global_arr (struct S *s)
+{
+  strncpy (s->a, arr, sizeof s->a - 1);     /* { dg-bogus "\\\[-Wstringop-truncation]" } */
+  s->a [sizeof s->a - 1] = '\0';
+}
+
+void test_global_arr2 (struct S *s)
+{
+  strncpy (s->a, arr2[1], sizeof s->a - 1); /* { dg-bogus "\\\[-Wstringop-truncation]" } */
+  s->a [sizeof s->a - 1] = '\0';
+
+  strncpy (s->b, arr2[0], sizeof s->a - 1);
+}
+
+void test_global_ptr (struct S *s)
+{
+  strncpy (s->a, ptr, sizeof s->a - 1);     /* { dg-bogus "\\\[-Wstringop-truncation]" } */
+  s->a [sizeof s->a - 1] = '\0';
+}
+
+void test_local_arr (struct S *s)
+{
+  const char arr[] = STR;
+  strncpy (s->a, arr, sizeof s->a - 1);
+  s->a [sizeof s->a - 1] = '\0';
+}
+
+void test_local_ptr (struct S *s)
+{
+  const char* const ptr = STR;
+  strncpy (s->a, ptr, sizeof s->a - 1);     /* { dg-bogus "\\\[-Wstringop-truncation]" } */
+  s->a [sizeof s->a - 1] = '\0';
+}
+
+void test_compound_literal (struct S *s)
+{
+  strncpy (s->a, (char[]){ STR }, sizeof s->a - 1);
+  s->a [sizeof s->a - 1] = '\0';
+}
+/* PR tree-optimization/87028 - false positive -Wstringop-truncation
+   strncpy with global variable source string
+   { dg-do compile }
+   { dg-options "-O2 -Wstringop-truncation" } */
+
+char *strncpy (char *, const char *, __SIZE_TYPE__);
+
+#define STR   "1234567890"
+
+struct S
+{
+  char a[5], b[5];
+};
+
+const char arr[] = STR;
+const char* const ptr = STR;
+
+const char arr2[][10] = { "123", STR };
+
+void test_literal (struct S *s)
+{
+  strncpy (s->a, STR, sizeof s->a - 1);     /* { dg-bogus "\\\[-Wstringop-truncation]" } */
+  s->a[sizeof s->a - 1] = '\0';
+}
+
+void test_global_arr (struct S *s)
+{
+  strncpy (s->a, arr, sizeof s->a - 1);     /* { dg-bogus "\\\[-Wstringop-truncation]" } */
+  s->a [sizeof s->a - 1] = '\0';
+}
+
+void test_global_arr2 (struct S *s)
+{
+  strncpy (s->a, arr2[1], sizeof s->a - 1); /* { dg-bogus "\\\[-Wstringop-truncation]" } */
+  s->a [sizeof s->a - 1] = '\0';
+
+  strncpy (s->b, arr2[0], sizeof s->a - 1);
+}
+
+void test_global_ptr (struct S *s)
+{
+  strncpy (s->a, ptr, sizeof s->a - 1);     /* { dg-bogus "\\\[-Wstringop-truncation]" } */
+  s->a [sizeof s->a - 1] = '\0';
+}
+
+void test_local_arr (struct S *s)
+{
+  const char arr[] = STR;
+  strncpy (s->a, arr, sizeof s->a - 1);
+  s->a [sizeof s->a - 1] = '\0';
+}
+
+void test_local_ptr (struct S *s)
+{
+  const char* const ptr = STR;
+  strncpy (s->a, ptr, sizeof s->a - 1);     /* { dg-bogus "\\\[-Wstringop-truncation]" } */
+  s->a [sizeof s->a - 1] = '\0';
+}
+
+void test_compound_literal (struct S *s)
+{
+  strncpy (s->a, (char[]){ STR }, sizeof s->a - 1);
+  s->a [sizeof s->a - 1] = '\0';
+}
index ed6cd0603392ac445ac28a93d53b37d1423f6c70..9a5448465eea0bb713fbdf6a946aabee9b8001b3 100644 (file)
@@ -1,6 +1,6 @@
 /* PR tree-optimization/80933 - redundant bzero/bcopy calls not eliminated
    { dg-do compile }
-   { dg-options "-O0 -Wall -fdump-tree-gimple" } */
+   { dg-options "-O1 -Wall -fdump-tree-lower" } */
 
 void f0 (void *dst, const void *src, unsigned n)
 {
@@ -46,9 +46,9 @@ void f6 (void *p)
 /* Verify that calls to bcmp, bcopy, and bzero have all been removed
    and one of each replaced with memcmp, memmove, and memset, respectively.
    The remaining three should be eliminated.
-  { dg-final { scan-tree-dump-not "bcmp|bcopy|bzero" "gimple" } }
-  { dg-final { scan-tree-dump-times "memcmp|memmove|memset" 3 "gimple" } }
+  { dg-final { scan-tree-dump-not "bcmp|bcopy|bzero" "lower" } }
+  { dg-final { scan-tree-dump-times "memcmp|memmove|memset" 3 "lower" } }
 
   Verify that the bcopy to memmove transformation correctly transposed
   the source and destination pointer arguments.
-  { dg-final { scan-tree-dump-times "memmove \\(dst, src" 1 "gimple" } }  */
+  { dg-final { scan-tree-dump-times "memmove \\(dst, src" 1 "lower" } }  */
index 40596a20b40088d643ccc0a4f60e5cf5005a8a2b..b1e0bc3b274ed6bd3e0c4ed874506d39c9be5d90 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-options "-fdump-tree-gimple" } */
+/* { dg-options "-fdump-tree-lower" } */
 
 #include <string.h>
 #include <stdlib.h>
@@ -25,4 +25,4 @@ int main ()
   return 0;
 }
 
-/* { dg-final { scan-tree-dump-times "strcmp \\(" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "strcmp \\(" 2 "lower" } } */
index fc3580e3ce34d867488470e25ac4efdc3578fee2..973ec0dc1937a0cfa4c0d420c6e3387cba9c3af9 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-gimple -fdump-tree-cddce-details -fdump-tree-optimized" } */
+/* { dg-options "-O2 -fdump-tree-lower -fdump-tree-cddce-details -fdump-tree-optimized" } */
 
 void f(void)
 {
@@ -18,4 +18,4 @@ void h(void)
 
 /* { dg-final { scan-tree-dump "Deleting : __builtin_strdup" "cddce1" } } */
 /* { dg-final { scan-tree-dump "Deleting : __builtin_strndup" "cddce1" } } */
-/* { dg-final { scan-tree-dump "__builtin_malloc" "gimple" } } */
+/* { dg-final { scan-tree-dump "__builtin_malloc" "lower" } } */