diff mbox series

[committed,middle-end/88663] Simplify get_range_strlen and fix test of return value

Message ID 88be3614-c565-13bb-247d-2c59fcbf168a@redhat.com
State New
Headers show
Series [committed,middle-end/88663] Simplify get_range_strlen and fix test of return value | expand

Commit Message

Jeff Law Jan. 2, 2019, 6:30 p.m. UTC
This fixes pr88663.

We drop the flexp special handling and instead handle the trailing array
just like any other situation where we need to be conservative.  It also
removes some special casing when we had an unterminated character array.
 Generic code handles that just fine now.  Make return value from
get_range_strlen more consistent.    Most importantly it fixes the tense
of a return value check in gimple_fold_builtin_strlen.

Bootstrapped and regression tested on x86_64.  Spot tested on a 32bit
port (crisv32 which was showing the same failure as HJ reported).  I've
got a dozen or so other 32bit ports which showed overnight failures that
I suspect are the same thing.  I'll spin those independently to confirm
and take appropriate actions.

Installing on the trunk.

Jeff
commit 9fd69efdd821c1afeb25e5469ed36993426adb37
Author: Jeff Law <law@torsion.usersys.redhat.com>
Date:   Fri Dec 21 17:50:22 2018 -0500

            PR middle-end/88663
            * gimple-fold.c (get_range_strlen): Update prototype to no longer
            need the flexp argument.
            (get_range_strlen_tree): Drop flexp argument.  Drop flexp argument
            from calls to get_range_strlen.  Update comments.  Just update
            VAL for an unterminated const char array and let the reset of the
            code handle it normally.  No longer try to set *flexp.  Adjust
            return value.
            (get_range_strlen): Update for the new get_range_strlen API.
            (get_maxval_strlen): Similarly.
            (gimple_fold_builtin_strlen): Handle update meaning of return value
            from get_range_strlen.
            * gimple-ssa-sprintf.c (get_string_length): Update for the new
            get_range_strlen API.
diff mbox series

Patch

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 708eb500cf2..b344f6be61e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,21 @@ 
+2019-01-02  Martin Sebor  <msebor@redhat.com>
+            Jeff Law  <law@redhat.com>
+
+	PR middle-end/88663
+	* gimple-fold.c (get_range_strlen): Update prototype to no longer
+	need the flexp argument.
+	(get_range_strlen_tree): Drop flexp argument.  Drop flexp argument
+	from calls to get_range_strlen.  Update comments.  Just update
+	VAL for an unterminated const char array and let the reset of the
+	code handle it normally.  No longer try to set *flexp.  Adjust
+	return value.
+	(get_range_strlen): Update for the new get_range_strlen API.
+	(get_maxval_strlen): Similarly.
+	(gimple_fold_builtin_strlen): Handle update meaning of return value
+	from get_range_strlen.
+	* gimple-ssa-sprintf.c (get_string_length): Update for the new
+	get_range_strlen API.
+	
 2019-01-02  Jan Hubicka  <hubicka@ucw.cz>
 
 	PR lto/88130
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index cf19db268ad..688daf92154 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -83,8 +83,8 @@  enum strlen_range_kind {
   SRK_INT_VALUE
 };
 
-static bool get_range_strlen (tree, bitmap *, strlen_range_kind,
-		  c_strlen_data *, bool *, unsigned);
+static bool
+get_range_strlen (tree, bitmap *, strlen_range_kind, c_strlen_data *, 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,10 +1281,8 @@  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, bitmap *visited,
-		       strlen_range_kind rkind,
-		       c_strlen_data *pdata,
-		       bool *flexp, unsigned eltsize)
+get_range_strlen_tree (tree arg, bitmap *visited, strlen_range_kind rkind,
+		       c_strlen_data *pdata, unsigned eltsize)
 {
   gcc_assert (TREE_CODE (arg) != SSA_NAME);
  
@@ -1307,8 +1305,8 @@  get_range_strlen_tree (tree arg, 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), visited,
-				     rkind, pdata, flexp, eltsize);
+	    return get_range_strlen (TREE_OPERAND (aop0, 0), visited, rkind,
+				     pdata, eltsize);
 	}
       else if (TREE_CODE (TREE_OPERAND (op, 0)) == COMPONENT_REF
 	       && (rkind == SRK_LENRANGE || rkind == SRK_LENRANGE_2))
@@ -1342,14 +1340,12 @@  get_range_strlen_tree (tree arg, bitmap *visited,
       c_strlen_data lendata = { };
       val = c_strlen (arg, 1, &lendata, eltsize);
 
-      /* If we potentially had a non-terminated string, then
-	 bubble that information up to the caller.  */
       if (!val && lendata.decl)
 	{
+	  /* ARG refers to an unterminated const character array.
+	     DATA.DECL with size DATA.LEN.  */
+	  val = lendata.minlen;
 	  pdata->decl = lendata.decl;
-	  pdata->minlen = lendata.minlen;
-	  pdata->maxlen = lendata.minlen;
-	  return rkind == SRK_STRLEN ? false : true;
 	}
     }
 
@@ -1357,7 +1353,7 @@  get_range_strlen_tree (tree arg, bitmap *visited,
     {
       if (TREE_CODE (arg) == ADDR_EXPR)
 	return get_range_strlen (TREE_OPERAND (arg, 0), visited, rkind,
-				 pdata, flexp, eltsize);
+				 pdata, eltsize);
 
       if (TREE_CODE (arg) == ARRAY_REF)
 	{
@@ -1386,10 +1382,6 @@  get_range_strlen_tree (tree arg, bitmap *visited,
 	     the array could have zero length.  */
 	  pdata->minlen = ssize_int (0);
 
-	  if (TREE_CODE (TREE_OPERAND (arg, 0)) == COMPONENT_REF
-	      && optype == TREE_TYPE (TREE_OPERAND (arg, 0))
-	      && array_at_struct_end_p (TREE_OPERAND (arg, 0)))
-	    *flexp = true;
 	  tight_bound = true;
 	}
       else if (TREE_CODE (arg) == COMPONENT_REF
@@ -1401,11 +1393,7 @@  get_range_strlen_tree (tree arg, bitmap *visited,
 	     optimistic if the array itself isn't NUL-terminated and
 	     the caller relies on the subsequent member to contain
 	     the NUL but that would only be considered valid if
-	     the array were the last member of a struct.
-	      Set *FLEXP to true if the array whose bound is being
-	     used is at the end of a struct.  */
-	  if (array_at_struct_end_p (arg))
-	    *flexp = true;
+	     the array were the last member of a struct.  */
 
 	  tree fld = TREE_OPERAND (arg, 1);
 
@@ -1550,7 +1538,7 @@  get_range_strlen_tree (tree arg, bitmap *visited,
     }
 
   pdata->maxlen = val;
-  return true;
+  return rkind == SRK_LENRANGE || rkind == SRK_LENRANGE_2 || !integer_all_onesp (val);
 }
 
 /* For an ARG referencing one or more strings, try to obtain the range
@@ -1570,12 +1558,13 @@  get_range_strlen_tree (tree arg, bitmap *visited,
    Return true if *PDATA was successfully populated and false otherwise.  */
 
 static bool
-get_range_strlen (tree arg, bitmap *visited, strlen_range_kind rkind,
-		  c_strlen_data *pdata, bool *flexp, unsigned eltsize)
+get_range_strlen (tree arg, bitmap *visited,
+		  strlen_range_kind rkind,
+		  c_strlen_data *pdata, unsigned eltsize)
 {
 
   if (TREE_CODE (arg) != SSA_NAME)
-    return get_range_strlen_tree (arg, visited, rkind, pdata, flexp, eltsize);
+    return get_range_strlen_tree (arg, visited, rkind, pdata, eltsize);
 
   /* If ARG is registered for SSA update we cannot look at its defining
      statement.  */
@@ -1601,7 +1590,7 @@  get_range_strlen (tree arg, bitmap *visited, strlen_range_kind rkind,
             || gimple_assign_unary_nop_p (def_stmt))
           {
 	    tree rhs = gimple_assign_rhs1 (def_stmt);
-	    return get_range_strlen (rhs, visited, rkind, pdata, flexp, eltsize);
+	    return get_range_strlen (rhs, visited, rkind, pdata, eltsize);
           }
 	else if (gimple_assign_rhs_code (def_stmt) == COND_EXPR)
 	  {
@@ -1609,8 +1598,7 @@  get_range_strlen (tree arg, bitmap *visited, strlen_range_kind rkind,
 			    gimple_assign_rhs3 (def_stmt) };
 
 	    for (unsigned int i = 0; i < 2; i++)
-	      if (!get_range_strlen (ops[i], visited, rkind, pdata,
-				     flexp, eltsize))
+	      if (!get_range_strlen (ops[i], visited, rkind, pdata, eltsize))
 		{
 		  if (rkind != SRK_LENRANGE_2)
 		    return false;
@@ -1644,7 +1632,7 @@  get_range_strlen (tree arg, bitmap *visited, strlen_range_kind rkind,
             if (arg == gimple_phi_result (def_stmt))
               continue;
 
-	    if (!get_range_strlen (arg, visited, rkind, pdata, flexp, eltsize))
+	    if (!get_range_strlen (arg, visited, rkind, pdata, eltsize))
 	      {
 		if (rkind != SRK_LENRANGE_2)
 		  return false;
@@ -1696,8 +1684,8 @@  get_range_strlen (tree arg, c_strlen_data *pdata, unsigned eltsize, bool strict)
 {
   bitmap visited = NULL;
 
-  bool flexarray = false;
-  if (!get_range_strlen (arg, &visited, strict ? SRK_LENRANGE : SRK_LENRANGE_2, pdata, &flexarray, eltsize))
+  if (!get_range_strlen (arg, &visited, strict ? SRK_LENRANGE : SRK_LENRANGE_2,
+			 pdata, eltsize))
     {
       /* On failure extend the length range to an impossible maximum
 	 (a valid MAXLEN must be less than PTRDIFF_MAX - 1).  Other
@@ -1715,7 +1703,7 @@  get_range_strlen (tree arg, c_strlen_data *pdata, unsigned eltsize, bool strict)
   if (visited)
     BITMAP_FREE (visited);
 
-  return flexarray;
+  return !integer_all_onesp (pdata->maxlen);
 }
 
 /* Return the maximum value for ARG given RKIND (see strlen_range_kind).
@@ -1741,8 +1729,7 @@  get_maxval_strlen (tree arg, strlen_range_kind rkind, tree *nonstr = NULL)
   /* Reset DATA.MAXLEN if the call fails or when DATA.MAXLEN
      is unbounded.  */
   c_strlen_data lendata = { };
-  bool dummy;
-  if (!get_range_strlen (arg, &visited, rkind, &lendata, &dummy, 1))
+  if (!get_range_strlen (arg, &visited, rkind, &lendata, /* eltsize = */1))
     lendata.maxlen = NULL_TREE;
   else if (lendata.maxlen && integer_all_onesp (lendata.maxlen))
     lendata.maxlen = NULL_TREE;
@@ -3720,7 +3707,7 @@  gimple_fold_builtin_strlen (gimple_stmt_iterator *gsi)
   wide_int maxlen;
 
   c_strlen_data lendata = { };
-  if (!get_range_strlen (arg, &lendata, /* eltsize = */ 1)
+  if (get_range_strlen (arg, &lendata, /* eltsize = */ 1)
       && !lendata.decl
       && lendata.minlen && TREE_CODE (lendata.minlen) == INTEGER_CST
       && lendata.maxlen && TREE_CODE (lendata.maxlen) == INTEGER_CST)
diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c
index 65aab5ba092..8e6016fc42f 100644
--- a/gcc/gimple-ssa-sprintf.c
+++ b/gcc/gimple-ssa-sprintf.c
@@ -2009,7 +2009,7 @@  get_string_length (tree str, unsigned eltsize)
      aren't known to point any such arrays result in LENDATA.MAXLEN
      set to SIZE_MAX.  */
   c_strlen_data lendata = { };
-  bool flexarray = get_range_strlen (str, &lendata, eltsize);
+  get_range_strlen (str, &lendata, eltsize);
 
   /* Return the default result when nothing is known about the string. */
   if (integer_all_onesp (lendata.maxbound)
@@ -2026,7 +2026,7 @@  get_string_length (tree str, unsigned eltsize)
        ? tree_to_uhwi (lendata.maxbound)
        : HOST_WIDE_INT_M1U);
 
-  const bool unbounded = flexarray || integer_all_onesp (lendata.maxlen);
+  const bool unbounded = integer_all_onesp (lendata.maxlen);
 
   /* Set the max/likely counters to unbounded when a minimum is known
      but the maximum length isn't bounded.  This implies that STR is