PR tree-optimization/91570 - ICE in get_range_strlen_dynamic on a conditional
authorMartin Sebor <msebor@redhat.com>
Tue, 24 Sep 2019 19:04:54 +0000 (19:04 +0000)
committerMartin Sebor <msebor@gcc.gnu.org>
Tue, 24 Sep 2019 19:04:54 +0000 (13:04 -0600)
PR tree-optimization/91570 - ICE in get_range_strlen_dynamic on a conditional
of two strings

gcc/Changelog:
* tree-ssa-strlen.c (get_range_strlen_dynamic): Handle null and
non-constant minlen, maxlen and maxbound.

gcc/testsuite/Changelog:
* gcc.dg/pr91570.c: New test.

From-SVN: r276105

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

index 47f3a006a325e0f6ed306e3ba3d36075385ce5e1..ab0cef72f2b24a39029c9c31ff327bf23d94719e 100644 (file)
@@ -1,3 +1,9 @@
+2019-09-23  Martin Sebor  <msebor@redhat.com>
+
+       PR tree-optimization/91570
+       * tree-ssa-strlen.c (get_range_strlen_dynamic): Handle null and
+       non-constant minlen, maxlen and maxbound.
+
 2019-09-24  Richard Biener  <rguenther@suse.de>
 
        * tree-vectorizer.h (_stmt_vec_info::const_cond_reduc_code):
index b90eb6d13ca05666c526c46b24900e8029ed6cc3..f1f670bf0cfd05ec8236edeb637f7b36cd6ac76a 100644 (file)
@@ -1,3 +1,8 @@
+2019-09-23  Martin Sebor  <msebor@redhat.com>
+
+       PR tree-optimization/91570
+       * gcc.dg/pr91570.c: New test.
+
 2019-09-24  Marek Polacek  <polacek@redhat.com>
 
        PR c++/91868 - improve -Wshadow location.
diff --git a/gcc/testsuite/gcc.dg/pr91570.c b/gcc/testsuite/gcc.dg/pr91570.c
new file mode 100644 (file)
index 0000000..03f2686
--- /dev/null
@@ -0,0 +1,30 @@
+/* PR tree-optimization/91570 - ICE in get_range_strlen_dynamic on
+   a conditional of two strings
+   { dg-do compile }
+   { dg-options "-O2 -Wall" } */
+
+extern char a[], b[];
+
+/* Test case from comment #0 on the bug.  */
+
+void comment_0 (int i)
+{
+  a[0] = 0;
+  b[0] = '1';
+
+  const char *p = i ? b : a;
+
+  if (__builtin_snprintf (0, 0, "%s", p) < 4)
+    __builtin_abort ();
+}
+
+
+/* Test case from comment #2 on the bug.  */
+
+void comment_2 (char *s)
+{
+  char *t = __builtin_strrchr (s, '/');
+  __builtin_strcat (s, ".SIF");
+  t = t ? t : s;
+  __builtin_printf ("%s", t);
+}
index 5e1054be48e2a792cad6dcc0876dbd145f9b3af6..c82bc7c481555bee76f5f021a6c0f7941b8f11db 100644 (file)
@@ -896,7 +896,8 @@ get_range_strlen_dynamic (tree src, c_strlen_data *pdata, bitmap *visited,
 
                      if (!argdata.minlen
                          || (integer_zerop (argdata.minlen)
-                             && integer_all_onesp (argdata.maxbound)
+                             && (!argdata.maxbound
+                                 || integer_all_onesp (argdata.maxbound))
                              && integer_all_onesp (argdata.maxlen)))
                        {
                          /* Set the upper bound of the length to unbounded.  */
@@ -910,11 +911,13 @@ get_range_strlen_dynamic (tree src, c_strlen_data *pdata, bitmap *visited,
                          || tree_int_cst_lt (argdata.minlen, pdata->minlen))
                        pdata->minlen = argdata.minlen;
                      if (!pdata->maxlen
-                         || tree_int_cst_lt (pdata->maxlen, argdata.maxlen))
+                         || (argdata.maxlen
+                             && tree_int_cst_lt (pdata->maxlen, argdata.maxlen)))
                        pdata->maxlen = argdata.maxlen;
                      if (!pdata->maxbound
-                         || (tree_int_cst_lt (pdata->maxbound,
-                                              argdata.maxbound)
+                         || (argdata.maxbound
+                             && tree_int_cst_lt (pdata->maxbound,
+                                                 argdata.maxbound)
                              && !integer_all_onesp (argdata.maxbound)))
                        pdata->maxbound = argdata.maxbound;
                    }
@@ -944,8 +947,7 @@ get_range_strlen_dynamic (tree src, c_strlen_data *pdata, bitmap *visited,
   if (strinfo *si = get_strinfo (idx))
     {
       pdata->minlen = get_string_length (si);
-      if (!pdata->minlen
-         && si->nonzero_chars)
+      if (!pdata->minlen && si->nonzero_chars)
        {
          if (TREE_CODE (si->nonzero_chars) == INTEGER_CST)
            pdata->minlen = si->nonzero_chars;
@@ -989,7 +991,7 @@ get_range_strlen_dynamic (tree src, c_strlen_data *pdata, bitmap *visited,
          else
            pdata->maxlen = build_all_ones_cst (size_type_node);
        }
-      else if (TREE_CODE (pdata->minlen) == SSA_NAME)
+      else if (pdata->minlen && TREE_CODE (pdata->minlen) == SSA_NAME)
        {
          const value_range *vr
            = CONST_CAST (class vr_values *, rvals)
@@ -1007,11 +1009,19 @@ get_range_strlen_dynamic (tree src, c_strlen_data *pdata, bitmap *visited,
              pdata->maxlen = build_all_ones_cst (size_type_node);
            }
        }
-      else
+      else if (pdata->minlen && TREE_CODE (pdata->minlen) == INTEGER_CST)
        {
          pdata->maxlen = pdata->minlen;
          pdata->maxbound = pdata->minlen;
        }
+      else
+       {
+         /* For PDATA->MINLEN that's a non-constant expression such
+            as PLUS_EXPR whose value range is unknown, set the bounds
+            to zero and SIZE_MAX.  */
+         pdata->minlen = build_zero_cst (size_type_node);
+         pdata->maxlen = build_all_ones_cst (size_type_node);
+       }
 
       return true;
     }