PR tree-optimization/86400 - set<string>::set<char (*)[2]) constructor does not work...
authorMartin Sebor <msebor@redhat.com>
Thu, 5 Jul 2018 14:36:09 +0000 (14:36 +0000)
committerMartin Sebor <msebor@gcc.gnu.org>
Thu, 5 Jul 2018 14:36:09 +0000 (08:36 -0600)
gcc/ChangeLog:
* tree-ssa-strlen.c (maybe_set_strlen_range): Use type size rather
than its domain to compute its the upper bound of a char array.

gcc/testsuite/ChangeLog:
* gcc.dg/strlenopt-47.c: New test.
* gcc.dg/strlenopt-48.c: New test.

From-SVN: r262438

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/strlenopt-47.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/strlenopt-48.c [new file with mode: 0644]
gcc/tree-ssa-strlen.c

index 87cfd18bb268445b2ae3d641dcf605c715054363..adaacc57f6e5ee4278d8aa0e7d54cf94a9995eb4 100644 (file)
@@ -1,3 +1,9 @@
+2018-07-05  Martin Sebor  <msebor@redhat.com>
+
+       PR c++/86400
+       * tree-ssa-strlen.c (maybe_set_strlen_range): Use type size rather
+       than its domain to compute its the upper bound of a char array.
+
 2018-07-05  Nathan Sidwell  <nathan@acm.org>
 
        Replace NO_IMPLICIT_EXTERN_C with SYSTEM_IMPLICIT_EXTERN_C.
index c5acb6958882e1eddb9dcba673d5978d1dbd2f4e..9f2cc8410ca247c4af40f30f3d372261fb215b03 100644 (file)
@@ -1,3 +1,9 @@
+2018-07-05  Martin Sebor  <msebor@redhat.com>
+
+       PR c++/86400
+       * gcc.dg/strlenopt-47.c: New test.
+       * gcc.dg/strlenopt-48.c: New test.
+
 2018-07-05  Tamar Christina  <tamar.christina@arm.com>
 
        PR target/84711
diff --git a/gcc/testsuite/gcc.dg/strlenopt-47.c b/gcc/testsuite/gcc.dg/strlenopt-47.c
new file mode 100644 (file)
index 0000000..68945c7
--- /dev/null
@@ -0,0 +1,36 @@
+/* PR tree-optimization/86400 - set<string>::set<char (*)[2]) constructor
+   does not work with array argument
+   Verify that strlen() calls with two-character array elements of
+   multidimensional arrays whose higher order dimension is 1 are not
+   folded.
+   { dg-do compile }
+   { dg-options "-O2 -Wall -fdump-tree-optimized" } */
+
+#include "strlenopt.h"
+
+void f (void)
+{
+  extern char a[1][2];
+  int n = strlen (*a);
+  if (n != 1)
+    abort();
+}
+
+void g (void)
+{
+  extern char b[1][2];
+  int n = strlen (b[0]);
+  if (n != 1)
+    abort();
+}
+
+void h (void)
+{
+  extern char c[1][2];
+  int n = strlen (&c[0][0]);
+  if (n != 1)
+    abort();
+}
+
+/* { dg-final { scan-tree-dump-times "= strlen" 3 "optimized" } }
+   { dg-final { scan-tree-dump-times "abort" 3 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/strlenopt-48.c b/gcc/testsuite/gcc.dg/strlenopt-48.c
new file mode 100644 (file)
index 0000000..39bb32d
--- /dev/null
@@ -0,0 +1,35 @@
+/* PR tree-optimization/86400 - set<string>::set<char (*)[2]) constructor
+   does not work with array argument
+   Verify that strlen() calls with one-character array elements of
+   multidimensional arrays are still folded.
+   { dg-do compile }
+   { dg-options "-O2 -Wall -fdump-tree-optimized" } */
+
+#include "strlenopt.h"
+
+void f (void)
+{
+  extern char a[2][1];
+  int n = strlen (a[1]);
+  if (n)
+    abort();
+}
+
+void g (void)
+{
+  extern char b[3][2][1];
+  int n = strlen (b[2][1]);
+  if (n)
+    abort();
+}
+
+void h (void)
+{
+  extern char c[4][3][2][1];
+  int n = strlen (c[3][2][1]);
+  if (n)
+    abort();
+}
+
+/* { dg-final { scan-tree-dump-times "strlen" 0 "optimized" } }
+   { dg-final { scan-tree-dump-times "abort" 0 "optimized" } } */
index 5807c79f205ca8da79ef33941300febb64727c3c..736e2d946fc54d89adaf9cc26cea5fd0d703f1ea 100644 (file)
@@ -1156,22 +1156,17 @@ maybe_set_strlen_range (tree lhs, tree src, tree bound)
       if (src_is_array && !array_at_struct_end_p (src))
        {
          tree type = TREE_TYPE (src);
-         if (tree dom = TYPE_DOMAIN (type))
-           {
-             tree maxval = TYPE_MAX_VALUE (dom);
-             if (maxval)
-               max = wi::to_wide (maxval);
-             else
-               max = wi::zero (min.get_precision ());
-
-             /* For strlen() the upper bound above is equal to
-                the longest string that can be stored in the array
-                (i.e., it accounts for the terminating nul.  For
-                strnlen() bump up the maximum by one since the array
-                need not be nul-terminated.  */
-             if (bound)
-               ++max;
-           }
+         if (tree size = TYPE_SIZE_UNIT (type))
+           if (size && TREE_CODE (size) == INTEGER_CST)
+             max = wi::to_wide (size);
+
+         /* For strlen() the upper bound above is equal to
+            the longest string that can be stored in the array
+            (i.e., it accounts for the terminating nul.  For
+            strnlen() bump up the maximum by one since the array
+            need not be nul-terminated.  */
+         if (!bound && max != 0)
+           --max;
        }
       else
        {