aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2018-07-05 14:36:09 +0000
committerMartin Sebor <msebor@gcc.gnu.org>2018-07-05 08:36:09 -0600
commit715fcd73b66c639d9e0e3f3ef9c6ff9d621d7131 (patch)
treebf5e2c54a9f08d3e851b7523146bc2c9d4cc8238
parent09cff37bfdcc9407a72262cbdd6fd3350488d934 (diff)
downloadgcc-715fcd73b66c639d9e0e3f3ef9c6ff9d621d7131.zip
gcc-715fcd73b66c639d9e0e3f3ef9c6ff9d621d7131.tar.gz
gcc-715fcd73b66c639d9e0e3f3ef9c6ff9d621d7131.tar.bz2
PR tree-optimization/86400 - set<string>::set<char (*)[2]) constructor does not work with array argument
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
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-47.c36
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-48.c35
-rw-r--r--gcc/tree-ssa-strlen.c27
5 files changed, 94 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 87cfd18..adaacc5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c5acb69..9f2cc84 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..68945c7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/strlenopt-47.c
@@ -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
index 0000000..39bb32d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/strlenopt-48.c
@@ -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" } } */
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index 5807c79..736e2d9 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -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
{