PR tree-optimization/83896 - ice in get_string_len on a call to strlen with
authorMartin Sebor <msebor@redhat.com>
Fri, 26 Jan 2018 16:47:22 +0000 (16:47 +0000)
committerMartin Sebor <msebor@gcc.gnu.org>
Fri, 26 Jan 2018 16:47:22 +0000 (09:47 -0700)
PR tree-optimization/83896 - ice in get_string_len on a call to strlen with
non-constant length

gcc/ChangeLog:

        PR tree-optimization/83896
        * tree-ssa-strlen.c (get_string_len): Rename...
        (get_string_cst_length): ...to this.  Return HOST_WIDE_INT.
        Avoid assuming length is constant.
        (handle_char_store): Use HOST_WIDE_INT for string length.

gcc/testsuite/ChangeLog:

        PR tree-optimization/83896
        * gcc.dg/strlenopt-43.c: New test.

From-SVN: r257100

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

index a65cac117f3a945cce162c509b4dc4478f13b49a..d37cc7836fbf85705e32aaeffa97f41e15b0968f 100644 (file)
@@ -1,3 +1,11 @@
+2018-01-26  Martin Sebor  <msebor@redhat.com>
+
+       PR tree-optimization/83896
+       * tree-ssa-strlen.c (get_string_len): Rename...
+       (get_string_cst_length): ...to this.  Return HOST_WIDE_INT.
+       Avoid assuming length is constant.
+       (handle_char_store): Use HOST_WIDE_INT for string length.
+
 2018-01-26  Uros Bizjak  <ubizjak@gmail.com>
 
        PR target/81763
index adf8c01a82e8eb043c46ce29fcad5e6ec0d53a10..63bae36ea38071a7c2df23603cfc1b2a57e6b517 100644 (file)
@@ -1,3 +1,8 @@
+2018-01-26  Martin Sebor  <msebor@redhat.com>
+
+       PR tree-optimization/83896
+       * gcc.dg/strlenopt-43.c: New.
+
 2018-01-26  Will Schmidt  <will_schmidt@vnet.ibm.com>
 
        * gcc.target/powerpc/fold-vec-abs-int.c: Remove scan-assembler stanzas.
diff --git a/gcc/testsuite/gcc.dg/strlenopt-43.c b/gcc/testsuite/gcc.dg/strlenopt-43.c
new file mode 100644 (file)
index 0000000..13539fc
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR tree-optimization/83896 - ice in get_string_len on a call to strlen
+   with non-constant length
+   { dg-do compile }
+   { dg-options "-O2 -Wall" } */
+
+#include "strlenopt.h"
+
+extern char a[5];
+extern char b[];
+
+void f (void)
+{
+  if (strlen (b) != 4)
+    memcpy (a, b, sizeof a);
+}
index 4e363278ea21792b6a148a387ec169e3c1646dfd..c3cf432a9214089a2f03abbb73aa5e3bf63b74df 100644 (file)
@@ -2772,16 +2772,20 @@ handle_pointer_plus (gimple_stmt_iterator *gsi)
     }
 }
 
-/* Check if RHS is string_cst possibly wrapped by mem_ref.  */
-static int
-get_string_len (tree rhs)
+/* If RHS, either directly or indirectly, refers to a string of constant
+   length, return it.  Otherwise return a negative value.  */
+
+static HOST_WIDE_INT
+get_string_cst_length (tree rhs)
 {
   if (TREE_CODE (rhs) == MEM_REF
       && integer_zerop (TREE_OPERAND (rhs, 1)))
     {
-      tree rhs_addr = rhs = TREE_OPERAND (rhs, 0);
+      rhs = TREE_OPERAND (rhs, 0);
       if (TREE_CODE (rhs) == ADDR_EXPR)
        {
+         tree rhs_addr = rhs;
+
          rhs = TREE_OPERAND (rhs, 0);
          if (TREE_CODE (rhs) != STRING_CST)
            {
@@ -2789,7 +2793,9 @@ get_string_len (tree rhs)
              if (idx > 0)
                {
                  strinfo *si = get_strinfo (idx);
-                 if (si && si->full_string_p)
+                 if (si
+                     && si->full_string_p
+                     && tree_fits_shwi_p (si->nonzero_chars))
                    return tree_to_shwi (si->nonzero_chars);
                }
            }
@@ -2801,10 +2807,7 @@ get_string_len (tree rhs)
     rhs = DECL_INITIAL (rhs);
 
   if (rhs && TREE_CODE (rhs) == STRING_CST)
-    {
-      unsigned HOST_WIDE_INT ilen = strlen (TREE_STRING_POINTER (rhs));
-      return ilen <= INT_MAX ? ilen : -1;
-    }
+    return strlen (TREE_STRING_POINTER (rhs));
 
   return -1;
 }
@@ -2821,9 +2824,6 @@ handle_char_store (gimple_stmt_iterator *gsi)
   tree rhs = gimple_assign_rhs1 (stmt);
   unsigned HOST_WIDE_INT offset = 0;
 
-  /* Set to the length of the string being assigned if known.  */
-  int rhslen;
-
   if (TREE_CODE (lhs) == MEM_REF
       && TREE_CODE (TREE_OPERAND (lhs, 0)) == SSA_NAME)
     {
@@ -2854,6 +2854,8 @@ handle_char_store (gimple_stmt_iterator *gsi)
   bool storing_nonzero_p = (!storing_zero_p
                            && TREE_CODE (rhs) == INTEGER_CST
                            && integer_nonzerop (rhs));
+  /* Set to the length of the string being assigned if known.  */
+  HOST_WIDE_INT rhslen;
 
   if (si != NULL)
     {
@@ -2967,7 +2969,7 @@ handle_char_store (gimple_stmt_iterator *gsi)
        }
     }
   else if (idx == 0
-          && (rhslen = get_string_len (gimple_assign_rhs1 (stmt))) >= 0
+          && (rhslen = get_string_cst_length (gimple_assign_rhs1 (stmt))) >= 0
           && ssaname == NULL_TREE
           && TREE_CODE (TREE_TYPE (lhs)) == ARRAY_TYPE)
     {