gimple-fold.c (get_range_strlen): Update prototype.
authorMartin Sebor <msebor@redhat.com>
Tue, 1 Jan 2019 18:20:13 +0000 (18:20 +0000)
committerJeff Law <law@gcc.gnu.org>
Tue, 1 Jan 2019 18:20:13 +0000 (11:20 -0700)
* gimple-fold.c (get_range_strlen): Update prototype.
(get_range_strlen_tree): Update prototype.  Drop minlen/maxlen
local variables.  Use pdata to return information to caller.
Update calls to get_range_strlen.  Update pdata->maxbound.
(get_range_strlen -- static version): Similarly.
(get_range_strlen -- extern version): Update for internal
get_range_strlen API change.  Convert to external data format.
(get_maxval_strlen): Similarly.

Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r267498

gcc/ChangeLog
gcc/gimple-fold.c

index f7c7109a89fcc04b39c8aa055272ca1c5359922a..29fe552f2c49ef079f6ae01ebbde410c81f28fb3 100644 (file)
@@ -1,3 +1,15 @@
+2019-01-01  Martin Sebor  <msebor@redhat.com>
+            Jeff Law  <law@redhat.com>
+
+       * gimple-fold.c (get_range_strlen): Update prototype.
+       (get_range_strlen_tree): Update prototype.  Drop minlen/maxlen
+       local variables.  Use pdata to return information to caller.
+       Update calls to get_range_strlen.  Update pdata->maxbound.
+       (get_range_strlen -- static version): Similarly.
+       (get_range_strlen -- extern version): Update for internal
+       get_range_strlen API change.  Convert to external data format.
+       (get_maxval_strlen): Similarly.
+
 2019-01-01  Jan Hubicka  <hubicka@ucw.cz>
 
        * coverage.c (get_coverage_counts): Use current_function_decl.
index 3e7cbfd61e1ef371a949bd36d4d226018d3b0f82..5e29f79ee09d9988ef27f6ed250fcf41f121d78b 100644 (file)
@@ -83,8 +83,8 @@ enum strlen_range_kind {
   SRK_INT_VALUE
 };
 
-static bool get_range_strlen (tree, tree[2], bitmap *, strlen_range_kind,
-                 bool *, unsigned, tree *);
+static bool get_range_strlen (tree, bitmap *, strlen_range_kind,
+                 c_strlen_data *, bool *, unsigned);
 
 /* Return true when DECL can be referenced from current unit.
    FROM_DECL (if non-null) specify constructor of variable DECL was taken from.
@@ -1281,16 +1281,13 @@ gimple_fold_builtin_memset (gimple_stmt_iterator *gsi, tree c, tree len)
 /* Helper of get_range_strlen for ARG that is not an SSA_NAME.  */
 
 static bool
-get_range_strlen_tree (tree arg, tree length[2], bitmap *visited,
+get_range_strlen_tree (tree arg, bitmap *visited,
                       strlen_range_kind rkind,
-                      bool *flexp, unsigned eltsize, tree *nonstr)
+                      c_strlen_data *pdata,
+                      bool *flexp, unsigned eltsize)
 {
   gcc_assert (TREE_CODE (arg) != SSA_NAME);
  
-  /* The minimum and maximum length.  */
-  tree *const minlen = length;
-  tree *const maxlen = length + 1;
-
   /* The length computed by this invocation of the function.  */
   tree val = NULL_TREE;
 
@@ -1304,9 +1301,8 @@ get_range_strlen_tree (tree arg, tree length[2], bitmap *visited,
          tree aop0 = TREE_OPERAND (op, 0);
          if (TREE_CODE (aop0) == INDIRECT_REF
              && TREE_CODE (TREE_OPERAND (aop0, 0)) == SSA_NAME)
-           return get_range_strlen (TREE_OPERAND (aop0, 0), length,
-                                    visited, rkind, flexp,
-                                    eltsize, nonstr);
+           return get_range_strlen (TREE_OPERAND (aop0, 0), visited,
+                                    rkind, pdata, flexp, eltsize);
        }
       else if (TREE_CODE (TREE_OPERAND (op, 0)) == COMPONENT_REF
               && (rkind == SRK_LENRANGE || rkind == SRK_LENRANGE_2))
@@ -1344,9 +1340,9 @@ get_range_strlen_tree (tree arg, tree length[2], bitmap *visited,
         bubble that information up to the caller.  */
       if (!val && lendata.decl)
        {
-         *nonstr = lendata.decl;
-         *minlen = lendata.minlen;
-         *maxlen = lendata.minlen;
+         pdata->decl = lendata.decl;
+         pdata->minlen = lendata.minlen;
+         pdata->maxlen = lendata.minlen;
          return rkind == SRK_STRLEN ? false : true;
        }
     }
@@ -1354,9 +1350,8 @@ get_range_strlen_tree (tree arg, tree length[2], bitmap *visited,
   if (!val && (rkind == SRK_LENRANGE || rkind == SRK_LENRANGE_2))
     {
       if (TREE_CODE (arg) == ADDR_EXPR)
-       return get_range_strlen (TREE_OPERAND (arg, 0), length,
-                                visited, rkind, flexp,
-                                eltsize, nonstr);
+       return get_range_strlen (TREE_OPERAND (arg, 0), visited, rkind,
+                                pdata, flexp, eltsize);
 
       if (TREE_CODE (arg) == ARRAY_REF)
        {
@@ -1383,7 +1378,7 @@ get_range_strlen_tree (tree arg, tree length[2], bitmap *visited,
 
          /* Set the minimum size to zero since the string in
             the array could have zero length.  */
-         *minlen = ssize_int (0);
+         pdata->minlen = ssize_int (0);
 
          if (TREE_CODE (TREE_OPERAND (arg, 0)) == COMPONENT_REF
              && optype == TREE_TYPE (TREE_OPERAND (arg, 0))
@@ -1423,7 +1418,7 @@ get_range_strlen_tree (tree arg, tree length[2], bitmap *visited,
 
          /* Set the minimum size to zero since the string in
             the array could have zero length.  */
-         *minlen = ssize_int (0);
+         pdata->minlen = ssize_int (0);
        }
 
       if (VAR_P (arg))
@@ -1444,7 +1439,7 @@ get_range_strlen_tree (tree arg, tree length[2], bitmap *visited,
 
              /* Set the minimum size to zero since the string in
                 the array could have zero length.  */
-             *minlen = ssize_int (0);
+             pdata->minlen = ssize_int (0);
            }
        }
     }
@@ -1453,28 +1448,49 @@ get_range_strlen_tree (tree arg, tree length[2], bitmap *visited,
     return false;
 
   /* Adjust the lower bound on the string length as necessary.  */
-  if (!*minlen
+  if (!pdata->minlen
       || (rkind != SRK_STRLEN
-         && TREE_CODE (*minlen) == INTEGER_CST
+         && TREE_CODE (pdata->minlen) == INTEGER_CST
          && TREE_CODE (val) == INTEGER_CST
-         && tree_int_cst_lt (val, *minlen)))
-    *minlen = val;
+         && tree_int_cst_lt (val, pdata->minlen)))
+    pdata->minlen = val;
 
-  if (*maxlen)
+  if (pdata->maxbound)
+    {
+      /* Adjust the tighter (more optimistic) string length bound
+        if necessary and proceed to adjust the more conservative
+        bound.  */
+      if (TREE_CODE (val) == INTEGER_CST)
+       {
+         if (TREE_CODE (pdata->maxbound) == INTEGER_CST)
+           {
+             if (tree_int_cst_lt (pdata->maxbound, val))
+               pdata->maxbound = val;
+           }
+         else
+           pdata->maxbound = build_all_ones_cst (size_type_node);
+       }
+      else
+       pdata->maxbound = val;
+    }
+  else
+    pdata->maxbound = val;
+
+  if (pdata->maxlen)
     {
       /* Adjust the more conservative bound if possible/necessary
         and fail otherwise.  */
       if (rkind != SRK_STRLEN)
        {
-         if (TREE_CODE (*maxlen) != INTEGER_CST
+         if (TREE_CODE (pdata->maxlen) != INTEGER_CST
              || TREE_CODE (val) != INTEGER_CST)
            return false;
 
-         if (tree_int_cst_lt (*maxlen, val))
-           *maxlen = val;
+         if (tree_int_cst_lt (pdata->maxlen, val))
+           pdata->maxlen = val;
          return true;
        }
-      else if (simple_cst_equal (val, *maxlen) != 1)
+      else if (simple_cst_equal (val, pdata->maxlen) != 1)
        {
          /* Fail if the length of this ARG is different from that
             previously determined from another ARG.  */
@@ -1482,7 +1498,7 @@ get_range_strlen_tree (tree arg, tree length[2], bitmap *visited,
        }
     }
 
-  *maxlen = val;
+  pdata->maxlen = val;
   return true;
 }
 
@@ -1500,14 +1516,13 @@ get_range_strlen_tree (tree arg, tree length[2], bitmap *visited,
    Return true if *PDATA was successfully populated and false otherwise.  */
 
 static bool
-get_range_strlen (tree arg, tree length[2], bitmap *visited,
+get_range_strlen (tree arg, bitmap *visited,
                  strlen_range_kind rkind,
-                 bool *flexp, unsigned eltsize, tree *nonstr)
+                 c_strlen_data *pdata, bool *flexp, unsigned eltsize)
 {
 
   if (TREE_CODE (arg) != SSA_NAME)
-    return get_range_strlen_tree (arg, length, visited, rkind, flexp,
-                                 eltsize, nonstr);
+    return get_range_strlen_tree (arg, visited, rkind, pdata, flexp, eltsize);
 
   /* If ARG is registered for SSA update we cannot look at its defining
      statement.  */
@@ -1523,9 +1538,6 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited,
   tree var = arg;
   gimple *def_stmt = SSA_NAME_DEF_STMT (var);
 
-  /* The minimum and maximum length.  */
-  tree *const maxlen = length + 1;
-
   switch (gimple_code (def_stmt))
     {
       case GIMPLE_ASSIGN:
@@ -1536,8 +1548,7 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited,
             || gimple_assign_unary_nop_p (def_stmt))
           {
            tree rhs = gimple_assign_rhs1 (def_stmt);
-           return get_range_strlen (rhs, length, visited, rkind, flexp,
-                                    eltsize, nonstr);
+           return get_range_strlen (rhs, visited, rkind, pdata, flexp, eltsize);
           }
        else if (gimple_assign_rhs_code (def_stmt) == COND_EXPR)
          {
@@ -1545,8 +1556,8 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited,
                            gimple_assign_rhs3 (def_stmt) };
 
            for (unsigned int i = 0; i < 2; i++)
-             if (!get_range_strlen (ops[i], length, visited, rkind,
-                                    flexp, eltsize, nonstr))
+             if (!get_range_strlen (ops[i], visited, rkind, pdata,
+                                    flexp, eltsize))
                {
                  if (rkind != SRK_LENRANGE_2)
                    return false;
@@ -1558,7 +1569,7 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited,
                     in fact zero can be determined from MAXLEN being
                     unbounded but the discovered minimum is used for
                     diagnostics.  */
-                 *maxlen = build_all_ones_cst (size_type_node);
+                 pdata->maxlen = build_all_ones_cst (size_type_node);
                }
            return true;
          }
@@ -1580,8 +1591,7 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited,
             if (arg == gimple_phi_result (def_stmt))
               continue;
 
-           if (!get_range_strlen (arg, length, visited, rkind, flexp,
-                                  eltsize, nonstr))
+           if (!get_range_strlen (arg, visited, rkind, pdata, flexp, eltsize))
              {
                if (rkind != SRK_LENRANGE_2)
                  return false;
@@ -1593,7 +1603,7 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited,
                   in fact zero can be determined from MAXLEN being
                   unbounded but the discovered minimum is used for
                   diagnostics.  */
-               *maxlen = build_all_ones_cst (size_type_node);
+               pdata->maxlen = build_all_ones_cst (size_type_node);
              }
           }
         return true;
@@ -1642,14 +1652,21 @@ get_range_strlen (tree arg, tree minmaxlen[2], unsigned eltsize,
   *nonstr = NULL_TREE;
 
   bool flexarray = false;
-  if (!get_range_strlen (arg, minmaxlen, &visited,
+  c_strlen_data lendata = { };
+  if (!get_range_strlen (arg, &visited,
                         strict ? SRK_LENRANGE : SRK_LENRANGE_2,
-                        &flexarray, eltsize, nonstr))
+                        &lendata, &flexarray, eltsize))
     {
       minmaxlen[0] = NULL_TREE;
       minmaxlen[1] = NULL_TREE;
     }
+  else
+    {
+      minmaxlen[0] = lendata.minlen;
+      minmaxlen[1] = lendata.maxlen;
+    }
 
+  *nonstr = lendata.decl;
   if (visited)
     BITMAP_FREE (visited);
 
@@ -1674,13 +1691,11 @@ get_maxval_strlen (tree arg, strlen_range_kind rkind, tree *nonstr = NULL)
   gcc_assert (rkind != SRK_INT_VALUE || INTEGRAL_TYPE_P (TREE_TYPE (arg)));
 
   bitmap visited = NULL;
-  tree len[2] = { NULL_TREE, NULL_TREE };
 
   bool dummy;
-  /* Set to non-null if ARG refers to an untermianted array.  */
-  tree mynonstr = NULL_TREE;
-  if (!get_range_strlen (arg, len, &visited, rkind, &dummy, 1, &mynonstr))
-    len[1] = NULL_TREE;
+  c_strlen_data lendata = { };
+  if (!get_range_strlen (arg, &visited, rkind, &lendata, &dummy, 1))
+    lendata.maxlen = NULL_TREE;
   if (visited)
     BITMAP_FREE (visited);
 
@@ -1689,12 +1704,12 @@ get_maxval_strlen (tree arg, strlen_range_kind rkind, tree *nonstr = NULL)
       /* For callers prepared to handle unterminated arrays set
         *NONSTR to point to the declaration of the array and return
         the maximum length/size. */
-      *nonstr = mynonstr;
-      return len[1];
+      *nonstr = lendata.decl;
+      return lendata.maxlen;
     }
 
   /* Fail if the constant array isn't nul-terminated.  */
-  return mynonstr ? NULL_TREE : len[1];
+  return lendata.decl ? NULL_TREE : lendata.maxlen;
 }