[gcc(refs/users/aldyh/heads/ranger-staging)] Use range_query class in strlen/sprintf passes.

Aldy Hernandez aldyh@gcc.gnu.org
Thu Sep 10 08:15:08 GMT 2020


https://gcc.gnu.org/g:10d9fe7633cf5edeb171cc82a709096a52a4af23

commit 10d9fe7633cf5edeb171cc82a709096a52a4af23
Author: Aldy Hernandez <aldyh@redhat.com>
Date:   Wed Sep 9 12:11:48 2020 +0200

    Use range_query class in strlen/sprintf passes.

Diff:
---
 gcc/builtins.c           |  10 ++--
 gcc/builtins.h           |   5 +-
 gcc/gimple-ssa-sprintf.c | 136 +++++++++++++++++++++++++---------------------
 gcc/tree-ssa-strlen.c    | 137 +++++++++++++++++++++++------------------------
 gcc/tree-ssa-strlen.h    |   8 +--
 5 files changed, 153 insertions(+), 143 deletions(-)

diff --git a/gcc/builtins.c b/gcc/builtins.c
index fc6a0acf842..c9057fd9b79 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -3884,7 +3884,7 @@ check_access (tree exp, tree, tree, tree dstwrite,
 
 tree
 gimple_call_alloc_size (gimple *stmt, wide_int rng1[2] /* = NULL */,
-			const vr_values *rvals /* = NULL */)
+			range_query *rvals /* = NULL */)
 {
   if (!stmt)
     return NULL_TREE;
@@ -3975,7 +3975,7 @@ gimple_call_alloc_size (gimple *stmt, wide_int rng1[2] /* = NULL */,
 
 static bool
 get_range (tree x, gimple *stmt, signop sgn, offset_int r[2],
-	   const vr_values *rvals /* = NULL */)
+	   range_query *rvals /* = NULL */)
 {
   wide_int wr[2];
   if (!get_range (x, stmt, wr, rvals))
@@ -4002,7 +4002,7 @@ get_range (tree x, gimple *stmt, signop sgn, offset_int r[2],
 
 static bool
 compute_objsize (tree ptr, int ostype, access_ref *pref,
-		 bitmap *visited, const vr_values *rvals /* = NULL */)
+		 bitmap *visited, range_query *rvals /* = NULL */)
 {
   const bool addr = TREE_CODE (ptr) == ADDR_EXPR;
   if (addr)
@@ -4216,7 +4216,7 @@ compute_objsize (tree ptr, int ostype, access_ref *pref,
 
 static tree
 compute_objsize (tree ptr, int ostype, access_ref *pref,
-		 const vr_values *rvals = NULL)
+		 range_query *rvals = NULL)
 {
   bitmap visited = NULL;
 
@@ -4248,7 +4248,7 @@ compute_objsize (tree ptr, int ostype, access_ref *pref,
 
 tree
 compute_objsize (tree ptr, int ostype, tree *pdecl /* = NULL */,
-		 tree *poff /* = NULL */, const vr_values *rvals /* = NULL */)
+		 tree *poff /* = NULL */, class range_query *rvals /* = NULL */)
 {
   /* Set the initial offsets to zero and size to negative to indicate
      none has been computed yet.  */
diff --git a/gcc/builtins.h b/gcc/builtins.h
index 8b812ceb2c4..7212c427420 100644
--- a/gcc/builtins.h
+++ b/gcc/builtins.h
@@ -134,11 +134,10 @@ extern void set_builtin_user_assembler_name (tree decl, const char *asmspec);
 extern bool is_simple_builtin (tree);
 extern bool is_inexpensive_builtin (tree);
 
-class vr_values;
 tree gimple_call_alloc_size (gimple *, wide_int[2] = NULL,
-			     const vr_values * = NULL);
+			     class range_query * = NULL);
 extern tree compute_objsize (tree, int, tree * = NULL, tree * = NULL,
-			     const vr_values * = NULL);
+			     class range_query * = NULL);
 
 extern bool readonly_data_expr (tree exp);
 extern bool init_target_chars (void);
diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c
index f4688a86237..8b173987532 100644
--- a/gcc/gimple-ssa-sprintf.c
+++ b/gcc/gimple-ssa-sprintf.c
@@ -546,8 +546,8 @@ fmtresult::type_max_digits (tree type, int base)
 }
 
 static bool
-get_int_range (tree, HOST_WIDE_INT *, HOST_WIDE_INT *, bool, HOST_WIDE_INT,
-	       const vr_values *);
+get_int_range (tree, gimple *, HOST_WIDE_INT *, HOST_WIDE_INT *,
+	       bool, HOST_WIDE_INT, range_query *);
 
 struct call_info;
 
@@ -597,7 +597,7 @@ struct directive
 
   /* Format conversion function that given a directive and an argument
      returns the formatting result.  */
-  fmtresult (*fmtfunc) (const directive &, tree, const vr_values *);
+  fmtresult (*fmtfunc) (gimple *, const directive &, tree, range_query *);
 
   /* Return True when the format flag CHR has been used.  */
   bool get_flag (char chr) const
@@ -634,10 +634,7 @@ struct directive
      or 0, whichever is greater.  For a non-constant ARG in some range
      set width to its range adjusting each bound to -1 if it's less.
      For an indeterminate ARG set width to [0, INT_MAX].  */
-  void set_width (tree arg, const vr_values *vr)
-  {
-    get_int_range (arg, width, width + 1, true, 0, vr);
-  }
+  void set_width (tree arg, range_query *);
 
   /* Set both bounds of the precision range to VAL.  */
   void set_precision (HOST_WIDE_INT val)
@@ -650,10 +647,7 @@ struct directive
      or -1 whichever is greater.  For a non-constant ARG in some range
      set precision to its range adjusting each bound to -1 if it's less.
      For an indeterminate ARG set precision to [-1, INT_MAX].  */
-  void set_precision (tree arg, const vr_values *vr)
-  {
-    get_int_range (arg, prec, prec + 1, false, -1, vr);
-  }
+  void set_precision (tree arg, range_query *query);
 
   /* Return true if both width and precision are known to be
      either constant or in some range, false otherwise.  */
@@ -956,10 +950,22 @@ struct call_info
   }
 };
 
+void
+directive::set_width (tree arg, range_query *query)
+{
+  get_int_range (arg, info->callstmt, width, width + 1, true, 0, query);
+}
+
+void
+directive::set_precision (tree arg, range_query *query)
+{
+  get_int_range (arg, info->callstmt, prec, prec + 1, false, -1, query);
+}
+
 /* Return the result of formatting a no-op directive (such as '%n').  */
 
 static fmtresult
-format_none (const directive &, tree, const vr_values *)
+format_none (gimple *, const directive &, tree, range_query *)
 {
   fmtresult res (0);
   return res;
@@ -968,7 +974,7 @@ format_none (const directive &, tree, const vr_values *)
 /* Return the result of formatting the '%%' directive.  */
 
 static fmtresult
-format_percent (const directive &, tree, const vr_values *)
+format_percent (gimple *, const directive &, tree, range_query *)
 {
   fmtresult res (1);
   return res;
@@ -1026,9 +1032,10 @@ build_intmax_type_nodes (tree *pintmax, tree *puintmax)
    the determined range are replaced with NEGBOUND.  */
 
 static bool
-get_int_range (tree arg, HOST_WIDE_INT *pmin, HOST_WIDE_INT *pmax,
+get_int_range (tree arg, gimple *stmt,
+	       HOST_WIDE_INT *pmin, HOST_WIDE_INT *pmax,
 	       bool absolute, HOST_WIDE_INT negbound,
-	       const class vr_values *vr_values)
+	       range_query *query)
 {
   /* The type of the result.  */
   const_tree type = integer_type_node;
@@ -1067,10 +1074,11 @@ get_int_range (tree arg, HOST_WIDE_INT *pmin, HOST_WIDE_INT *pmax,
 	  && TYPE_PRECISION (argtype) <= TYPE_PRECISION (type))
 	{
 	  /* Try to determine the range of values of the integer argument.  */
-	  const value_range_equiv *vr
-	    = CONST_CAST (class vr_values *, vr_values)->get_value_range (arg);
+	  value_range vr;
+	  if (!query->range_of_expr (vr, arg, stmt))
+	    vr.set_varying (TREE_TYPE (arg));
 
-	  if (!vr->undefined_p () && !vr->varying_p () && !vr->symbolic_p ())
+	  if (!vr.undefined_p () && !vr.varying_p ())
 	    {
 	      HOST_WIDE_INT type_min
 		= (TYPE_UNSIGNED (argtype)
@@ -1080,8 +1088,8 @@ get_int_range (tree arg, HOST_WIDE_INT *pmin, HOST_WIDE_INT *pmax,
 	      HOST_WIDE_INT type_max = tree_to_uhwi (TYPE_MAX_VALUE (argtype));
 
 	      tree type = TREE_TYPE (arg);
-	      tree tmin = wide_int_to_tree (type, vr->lower_bound ());
-	      tree tmax = wide_int_to_tree (type, vr->upper_bound ());
+	      tree tmin = wide_int_to_tree (type, vr.lower_bound ());
+	      tree tmax = wide_int_to_tree (type, vr.upper_bound ());
 	      *pmin = TREE_INT_CST_LOW (tmin);
 	      *pmax = TREE_INT_CST_LOW (tmax);
 
@@ -1103,8 +1111,8 @@ get_int_range (tree arg, HOST_WIDE_INT *pmin, HOST_WIDE_INT *pmax,
       /* Handle an argument with an unknown range as if none had been
 	 provided.  */
       if (unknown)
-	return get_int_range (NULL_TREE, pmin, pmax, absolute,
-			      negbound, vr_values);
+	return get_int_range (NULL_TREE, NULL, pmin, pmax, absolute,
+			      negbound, query);
     }
 
   /* Adjust each bound as specified by ABSOLUTE and NEGBOUND.  */
@@ -1189,7 +1197,8 @@ adjust_range_for_overflow (tree dirtype, tree *argmin, tree *argmax)
    used when the directive argument or its value isn't known.  */
 
 static fmtresult
-format_integer (const directive &dir, tree arg, const vr_values *vr_values)
+format_integer (gimple *stmt, const directive &dir, tree arg,
+		range_query *query)
 {
   tree intmax_type_node;
   tree uintmax_type_node;
@@ -1372,13 +1381,14 @@ format_integer (const directive &dir, tree arg, const vr_values *vr_values)
     {
       /* Try to determine the range of values of the integer argument
 	 (range information is not available for pointers).  */
-      const value_range_equiv *vr
-	= CONST_CAST (class vr_values *, vr_values)->get_value_range (arg);
+      value_range vr;
+      if (!query->range_of_expr (vr, arg, stmt))
+	vr.set_varying (TREE_TYPE (arg));
 
-      if (!vr->varying_p () && !vr->undefined_p () && !vr->symbolic_p ())
+      if (!vr.varying_p () && !vr.undefined_p ())
 	{
-	  argmin = wide_int_to_tree (TREE_TYPE (arg), vr->lower_bound ());
-	  argmax = wide_int_to_tree (TREE_TYPE (arg), vr->upper_bound ());
+	  argmin = wide_int_to_tree (TREE_TYPE (arg), vr.lower_bound ());
+	  argmax = wide_int_to_tree (TREE_TYPE (arg), vr.upper_bound ());
 
 	  /* Set KNOWNRANGE if the argument is in a known subrange
 	     of the directive's type and neither width nor precision
@@ -1404,7 +1414,7 @@ format_integer (const directive &dir, tree arg, const vr_values *vr_values)
 	      if (code == INTEGER_CST)
 		{
 		  arg = gimple_assign_rhs1 (def);
-		  return format_integer (dir, arg, vr_values);
+		  return format_integer (def, dir, arg, query);
 		}
 
 	      if (code == NOP_EXPR)
@@ -1449,16 +1459,16 @@ format_integer (const directive &dir, tree arg, const vr_values *vr_values)
       /* For unsigned conversions/directives or signed when
 	 the minimum is positive, use the minimum and maximum to compute
 	 the shortest and longest output, respectively.  */
-      res.range.min = format_integer (dir, argmin, vr_values).range.min;
-      res.range.max = format_integer (dir, argmax, vr_values).range.max;
+      res.range.min = format_integer (stmt, dir, argmin, query).range.min;
+      res.range.max = format_integer (stmt, dir, argmax, query).range.max;
     }
   else if (tree_int_cst_sgn (argmax) < 0)
     {
       /* For signed conversions/directives if maximum is negative,
 	 use the minimum as the longest output and maximum as the
 	 shortest output.  */
-      res.range.min = format_integer (dir, argmax, vr_values).range.min;
-      res.range.max = format_integer (dir, argmin, vr_values).range.max;
+      res.range.min = format_integer (stmt, dir, argmax, query).range.min;
+      res.range.max = format_integer (stmt, dir, argmin, query).range.max;
     }
   else
     {
@@ -1467,11 +1477,11 @@ format_integer (const directive &dir, tree arg, const vr_values *vr_values)
 	 length of the output of both minimum and maximum and pick the
 	 longer.  */
       unsigned HOST_WIDE_INT max1
-	= format_integer (dir, argmin, vr_values).range.max;
+	= format_integer (stmt, dir, argmin, query).range.max;
       unsigned HOST_WIDE_INT max2
-	= format_integer (dir, argmax, vr_values).range.max;
+	= format_integer (stmt, dir, argmax, query).range.max;
       res.range.min
-	= format_integer (dir, integer_zero_node, vr_values).range.min;
+	= format_integer (stmt, dir, integer_zero_node, query).range.min;
       res.range.max = MAX (max1, max2);
     }
 
@@ -1820,7 +1830,7 @@ format_floating (const directive &dir, const HOST_WIDE_INT prec[2])
    ARG.  */
 
 static fmtresult
-format_floating (const directive &dir, tree arg, const vr_values *)
+format_floating (gimple *, const directive &dir, tree arg, range_query *)
 {
   HOST_WIDE_INT prec[] = { dir.prec[0], dir.prec[1] };
   tree type = (dir.modifier == FMT_LEN_L || dir.modifier == FMT_LEN_ll
@@ -2015,7 +2025,7 @@ format_floating (const directive &dir, tree arg, const vr_values *)
 
 static fmtresult
 get_string_length (tree str, gimple *stmt, unsigned eltsize,
-		   const vr_values *vr)
+		   range_query *query)
 {
   if (!str)
     return fmtresult ();
@@ -2026,7 +2036,7 @@ get_string_length (tree str, gimple *stmt, unsigned eltsize,
   c_strlen_data lendata = { };
   lendata.maxbound = str;
   if (eltsize == 1)
-    get_range_strlen_dynamic (str, stmt, &lendata, vr);
+    get_range_strlen_dynamic (str, stmt, &lendata, query);
   else
     {
       /* Determine the length of the shortest and longest string referenced
@@ -2123,7 +2133,8 @@ get_string_length (tree str, gimple *stmt, unsigned eltsize,
    vsprinf).  */
 
 static fmtresult
-format_character (const directive &dir, tree arg, const vr_values *vr_values)
+format_character (gimple *stmt, const directive &dir, tree arg,
+		  range_query *query)
 {
   fmtresult res;
 
@@ -2136,7 +2147,7 @@ format_character (const directive &dir, tree arg, const vr_values *vr_values)
       res.range.min = 0;
 
       HOST_WIDE_INT min, max;
-      if (get_int_range (arg, &min, &max, false, 0, vr_values))
+      if (get_int_range (arg, stmt, &min, &max, false, 0, query))
 	{
 	  if (min == 0 && max == 0)
 	    {
@@ -2434,7 +2445,8 @@ alias_offset (tree arg, tree dst, HOST_WIDE_INT dst_fld)
    vsprinf).  */
 
 static fmtresult
-format_string (const directive &dir, tree arg, const vr_values *vr_values)
+format_string (gimple *stmt, const directive &dir, tree arg,
+	       range_query *query)
 {
   fmtresult res;
 
@@ -2463,8 +2475,7 @@ format_string (const directive &dir, tree arg, const vr_values *vr_values)
       gcc_checking_assert (count_by == 2 || count_by == 4);
     }
 
-  gimple *stmt = dir.info->callstmt;
-  fmtresult slen = get_string_length (arg, stmt, count_by, vr_values);
+  fmtresult slen = get_string_length (arg, stmt, count_by, query);
   if (slen.range.min == slen.range.max
       && slen.range.min < HOST_WIDE_INT_MAX)
     {
@@ -2636,7 +2647,7 @@ format_string (const directive &dir, tree arg, const vr_values *vr_values)
 /* Format plain string (part of the format string itself).  */
 
 static fmtresult
-format_plain (const directive &dir, tree, const vr_values *)
+format_plain (gimple *, const directive &dir, tree, range_query *)
 {
   fmtresult res (dir.len);
   return res;
@@ -3032,7 +3043,7 @@ bytes_remaining (unsigned HOST_WIDE_INT navail, const format_result &res)
 static bool
 format_directive (const call_info &info,
 		  format_result *res, const directive &dir,
-		  const class vr_values *vr_values)
+		  range_query *query)
 {
   /* Offset of the beginning of the directive from the beginning
      of the format string.  */
@@ -3057,7 +3068,7 @@ format_directive (const call_info &info,
     return false;
 
   /* Compute the range of lengths of the formatted output.  */
-  fmtresult fmtres = dir.fmtfunc (dir, dir.arg, vr_values);
+  fmtresult fmtres = dir.fmtfunc (info.callstmt, dir, dir.arg, query);
 
   /* Record whether the output of all directives is known to be
      bounded by some maximum, implying that their arguments are
@@ -3388,7 +3399,7 @@ static size_t
 parse_directive (call_info &info,
 		 directive &dir, format_result *res,
 		 const char *str, unsigned *argno,
-		 const vr_values *vr_values)
+		 range_query *query)
 {
   const char *pcnt = strchr (str, target_percent);
   dir.beg = str;
@@ -3713,7 +3724,7 @@ parse_directive (call_info &info,
   if (star_width)
     {
       if (INTEGRAL_TYPE_P (TREE_TYPE (star_width)))
-	dir.set_width (star_width, vr_values);
+	dir.set_width (star_width, query);
       else
 	{
 	  /* Width specified by a va_list takes on the range [0, -INT_MIN]
@@ -3746,7 +3757,7 @@ parse_directive (call_info &info,
   if (star_precision)
     {
       if (INTEGRAL_TYPE_P (TREE_TYPE (star_precision)))
-	dir.set_precision (star_precision, vr_values);
+	dir.set_precision (star_precision, query);
       else
 	{
 	  /* Precision specified by a va_list takes on the range [-1, INT_MAX]
@@ -3960,7 +3971,8 @@ maybe_warn_overlap (call_info &info, format_result *res)
    that caused the processing to be terminated early).  */
 
 static bool
-compute_format_length (call_info &info, format_result *res, const vr_values *vr)
+compute_format_length (call_info &info, format_result *res,
+		       range_query *query)
 {
   if (dump_file)
     {
@@ -3997,10 +4009,10 @@ compute_format_length (call_info &info, format_result *res, const vr_values *vr)
     {
       directive dir (&info, dirno);
 
-      size_t n = parse_directive (info, dir, res, pf, &argno, vr);
+      size_t n = parse_directive (info, dir, res, pf, &argno, query);
 
       /* Return failure if the format function fails.  */
-      if (!format_directive (info, res, dir, vr))
+      if (!format_directive (info, res, dir, query))
 	return false;
 
       /* Return success when the directive is zero bytes long and it's
@@ -4290,13 +4302,14 @@ get_user_idx_format (tree fndecl, unsigned *idx_args)
    gsi_next should not be performed in the caller.  */
 
 bool
-handle_printf_call (gimple_stmt_iterator *gsi, const vr_values *vr_values)
+handle_printf_call (gimple_stmt_iterator *gsi, range_query *query)
 {
   init_target_to_host_charmap ();
 
   call_info info = call_info ();
 
-  info.callstmt = gsi_stmt (*gsi);
+  gimple *stmt = gsi_stmt (*gsi);
+  info.callstmt = stmt;
   info.func = gimple_call_fndecl (info.callstmt);
   if (!info.func)
     return false;
@@ -4559,14 +4572,15 @@ handle_printf_call (gimple_stmt_iterator *gsi, const vr_values *vr_values)
 	  /* Try to determine the range of values of the argument
 	     and use the greater of the two at level 1 and the smaller
 	     of them at level 2.  */
-	  const value_range_equiv *vr
-	    = CONST_CAST (class vr_values *, vr_values)->get_value_range (size);
+	  value_range vr;
+	  if (!query->range_of_expr (vr, size, stmt))
+	    vr.set_varying (TREE_TYPE (size));
 
-	  if (!vr->undefined_p () && !vr->symbolic_p ())
+	  if (!vr.undefined_p ())
 	    {
 	      tree type = TREE_TYPE (size);
-	      tree tmin = wide_int_to_tree (type, vr->lower_bound ());
-	      tree tmax = wide_int_to_tree (type, vr->upper_bound ());
+	      tree tmin = wide_int_to_tree (type, vr.lower_bound ());
+	      tree tmax = wide_int_to_tree (type, vr.upper_bound ());
 	      unsigned HOST_WIDE_INT minsize = TREE_INT_CST_LOW (tmin);
 	      unsigned HOST_WIDE_INT maxsize = TREE_INT_CST_LOW (tmax);
 	      dstsize = warn_level < 2 ? maxsize : minsize;
@@ -4677,7 +4691,7 @@ handle_printf_call (gimple_stmt_iterator *gsi, const vr_values *vr_values)
      never set to true again).  */
   res.posunder4k = posunder4k && dstptr;
 
-  bool success = compute_format_length (info, &res, vr_values);
+  bool success = compute_format_length (info, &res, query);
   if (res.warned)
     gimple_set_no_warning (info.callstmt, true);
 
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index 62828dfde1e..4a859f67c4e 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -201,7 +201,7 @@ static void handle_builtin_stxncpy_strncat (bool, gimple_stmt_iterator *);
 
 tree
 get_range (tree val, gimple *stmt, wide_int minmax[2],
-	   const vr_values *rvals /* = NULL */)
+	   range_query *rvals /* = NULL */)
 {
   if (TREE_CODE (val) == INTEGER_CST)
     {
@@ -214,19 +214,15 @@ get_range (tree val, gimple *stmt, wide_int minmax[2],
 
   if (rvals && stmt)
     {
-      /* The range below may be "inaccurate" if a constant has been
-	 substituted earlier for VAL by this pass that hasn't been
-	 propagated through the CFG.  This shoud be fixed by the new
-	 on-demand VRP if/when it becomes available (hopefully in
-	 GCC 11).  */
-      const value_range *vr
-	= (CONST_CAST (class vr_values *, rvals)->get_value_range (val, stmt));
-      value_range_kind rng = vr->kind ();
-      if (rng != VR_RANGE || !range_int_cst_p (vr))
+      value_range vr;
+      if (!rvals->range_of_expr (vr, val, stmt))
+	return NULL_TREE;
+      value_range_kind rng = vr.kind ();
+      if (rng != VR_RANGE)
 	return NULL_TREE;
 
-      minmax[0] = wi::to_wide (vr->min ());
-      minmax[1] = wi::to_wide (vr->max ());
+      minmax[0] = wi::to_wide (vr.min ());
+      minmax[1] = wi::to_wide (vr.max ());
       return val;
     }
 
@@ -264,7 +260,7 @@ compare_nonzero_chars (strinfo *si, unsigned HOST_WIDE_INT off)
 
 static int
 compare_nonzero_chars (strinfo *si, unsigned HOST_WIDE_INT off,
-		       const vr_values *rvals)
+		       range_query *rvals)
 {
   if (!si->nonzero_chars)
     return -1;
@@ -275,20 +271,19 @@ compare_nonzero_chars (strinfo *si, unsigned HOST_WIDE_INT off,
   if (!rvals || TREE_CODE (si->nonzero_chars) != SSA_NAME)
     return -1;
 
-  const value_range_equiv *vr
-    = (CONST_CAST (class vr_values *, rvals)
-       ->get_value_range (si->nonzero_chars, si->stmt));
-
-  value_range_kind rng = vr->kind ();
-  if (rng != VR_RANGE || !range_int_cst_p (vr))
+  value_range vr;
+  if (!rvals->range_of_expr (vr, si->nonzero_chars, si->stmt))
+    return -1;
+  value_range_kind rng = vr.kind ();
+  if (rng != VR_RANGE)
     return -1;
 
   /* If the offset is less than the minimum length or if the bounds
      of the length range are equal return the result of the comparison
      same as in the constant case.  Otherwise return a conservative
      result.  */
-  int cmpmin = compare_tree_int (vr->min (), off);
-  if (cmpmin > 0 || tree_int_cst_equal (vr->min (), vr->max ()))
+  int cmpmin = compare_tree_int (vr.min (), off);
+  if (cmpmin > 0 || tree_int_cst_equal (vr.min (), vr.max ()))
     return cmpmin;
 
   return -1;
@@ -333,7 +328,7 @@ get_next_strinfo (strinfo *si)
 
 static int
 get_addr_stridx (tree exp, tree ptr, unsigned HOST_WIDE_INT *offset_out,
-		 const vr_values *rvals = NULL)
+		 range_query *rvals = NULL)
 {
   HOST_WIDE_INT off;
   struct stridxlist *list, *last = NULL;
@@ -393,7 +388,7 @@ get_addr_stridx (tree exp, tree ptr, unsigned HOST_WIDE_INT *offset_out,
    When nonnull, uses RVALS to determine range information.  */
 
 static int
-get_stridx (tree exp, wide_int offrng[2] = NULL, const vr_values *rvals = NULL)
+get_stridx (tree exp, wide_int offrng[2] = NULL, range_query *rvals = NULL)
 {
   if (offrng)
     offrng[0] = offrng[1] = wi::zero (TYPE_PRECISION (ptrdiff_type_node));
@@ -869,7 +864,7 @@ get_string_length (strinfo *si)
    results.  */
 
 DEBUG_FUNCTION void
-dump_strlen_info (FILE *fp, gimple *stmt, const vr_values *rvals)
+dump_strlen_info (FILE *fp, gimple *stmt, range_query *rvals)
 {
   if (stmt)
     {
@@ -910,20 +905,20 @@ dump_strlen_info (FILE *fp, gimple *stmt, const vr_values *rvals)
 		      wide_int min, max;
 		      if (rvals)
 			{
-			  const value_range *vr
-			    = CONST_CAST (class vr_values *, rvals)
-			    ->get_value_range (si->nonzero_chars, si->stmt);
-			  rng = vr->kind ();
-			  if (range_int_cst_p (vr))
+			  value_range vr;
+			  if (!rvals->range_of_expr (vr, si->nonzero_chars,
+						     si->stmt))
+			    vr.set_varying (TREE_TYPE (si->nonzero_chars));
+			  rng = vr.kind ();
+			  if (range_int_cst_p (&vr))
 			    {
-			      min = wi::to_wide (vr->min ());
-			      max = wi::to_wide (vr->max ());
+			      min = wi::to_wide (vr.min ());
+			      max = wi::to_wide (vr.max ());
 			    }
 			  else
 			    rng = VR_UNDEFINED;
 			}
 		      else
-			// FIXME: call ranger
 			rng = get_range_info (si->nonzero_chars, &min, &max);
 
 		      if (rng == VR_RANGE || rng == VR_ANTI_RANGE)
@@ -1013,7 +1008,7 @@ dump_strlen_info (FILE *fp, gimple *stmt, const vr_values *rvals)
 static bool
 get_range_strlen_dynamic (tree src, gimple *stmt,
 			  c_strlen_data *pdata, bitmap *visited,
-			  const vr_values *rvals, unsigned *pssa_def_max)
+			  range_query *rvals, unsigned *pssa_def_max)
 {
   int idx = get_stridx (src);
   if (!idx)
@@ -1113,14 +1108,13 @@ get_range_strlen_dynamic (tree src, gimple *stmt,
 	    pdata->minlen = si->nonzero_chars;
 	  else if (TREE_CODE (si->nonzero_chars) == SSA_NAME)
 	    {
-	      const value_range_equiv *vr
-		= CONST_CAST (class vr_values *, rvals)
-		->get_value_range (si->nonzero_chars, si->stmt);
-	      if (vr->kind () == VR_RANGE
-		  && range_int_cst_p (vr))
+	      value_range vr;
+	      if (!rvals->range_of_expr (vr, si->nonzero_chars, si->stmt))
+		vr.set_varying (TREE_TYPE (si->nonzero_chars));
+	      if (range_int_cst_p (&vr))
 		{
-		  pdata->minlen = vr->min ();
-		  pdata->maxlen = vr->max ();
+		  pdata->minlen = vr.min ();
+		  pdata->maxlen = vr.max ();
 		}
 	      else
 		pdata->minlen = build_zero_cst (size_type_node);
@@ -1159,14 +1153,13 @@ get_range_strlen_dynamic (tree src, gimple *stmt,
 	}
       else if (pdata->minlen && TREE_CODE (pdata->minlen) == SSA_NAME)
 	{
-	  const value_range_equiv *vr
-	    = CONST_CAST (class vr_values *, rvals)
-	    ->get_value_range (si->nonzero_chars, stmt);
-	  if (vr->kind () == VR_RANGE
-	      && range_int_cst_p (vr))
+	  value_range vr;
+	  if (!rvals->range_of_expr (vr, si->nonzero_chars, stmt))
+	    vr.set_varying (TREE_TYPE (si->nonzero_chars));
+	  if (range_int_cst_p (&vr))
 	    {
-	      pdata->minlen = vr->min ();
-	      pdata->maxlen = vr->max ();
+	      pdata->minlen = vr.min ();
+	      pdata->maxlen = vr.max ();
 	      pdata->maxbound = pdata->maxlen;
 	    }
 	  else
@@ -1205,7 +1198,7 @@ get_range_strlen_dynamic (tree src, gimple *stmt,
 
 void
 get_range_strlen_dynamic (tree src, gimple *stmt, c_strlen_data *pdata,
-			  const vr_values *rvals)
+			  range_query *rvals)
 {
   bitmap visited = NULL;
   tree maxbound = pdata->maxbound;
@@ -1806,6 +1799,7 @@ set_strlen_range (tree lhs, wide_int min, wide_int max,
       else if (TREE_CODE (bound) == SSA_NAME)
 	{
 	  wide_int minbound, maxbound;
+	  // FIXME: have callers pass rvals and use range_query.
 	  value_range_kind rng = get_range_info (bound, &minbound, &maxbound);
 	  if (rng == VR_RANGE)
 	    {
@@ -1910,7 +1904,7 @@ maybe_set_strlen_range (tree lhs, tree src, tree bound)
 
 static void
 maybe_warn_overflow (gimple *stmt, tree len,
-		     const vr_values *rvals = NULL,
+		     range_query *rvals = NULL,
 		     strinfo *si = NULL, bool plus_one = false,
 		     bool rawmem = false)
 {
@@ -2342,7 +2336,7 @@ maybe_warn_overflow (gimple *stmt, tree len,
 
 static inline void
 maybe_warn_overflow (gimple *stmt, unsigned HOST_WIDE_INT len,
-		     const vr_values *rvals = NULL, strinfo *si = NULL,
+		     range_query *rvals = NULL, strinfo *si = NULL,
 		     bool plus_one = false, bool rawmem = false)
 {
   maybe_warn_overflow (stmt, build_int_cst (size_type_node, len), rvals,
@@ -2645,7 +2639,7 @@ handle_builtin_strchr (gimple_stmt_iterator *gsi)
 
 static void
 handle_builtin_strcpy (enum built_in_function bcode, gimple_stmt_iterator *gsi,
-		       const vr_values *rvals)
+		       range_query *rvals)
 {
   int idx, didx;
   tree src, dst, srclen, len, lhs, type, fn, oldlen;
@@ -3039,6 +3033,7 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt)
     cntrange[0] = cntrange[1] = wi::to_wide (cnt);
   else if (TREE_CODE (cnt) == SSA_NAME)
     {
+      // FIXME: Pass rvals and use range_query.
       enum value_range_kind rng = get_range_info (cnt, cntrange, cntrange + 1);
       if (rng == VR_RANGE)
 	;
@@ -3447,7 +3442,7 @@ handle_builtin_stxncpy_strncat (bool append_p, gimple_stmt_iterator *gsi)
 
 static void
 handle_builtin_memcpy (enum built_in_function bcode, gimple_stmt_iterator *gsi,
-		       const vr_values *rvals)
+		       range_query *rvals)
 {
   tree lhs, oldlen, newlen;
   gimple *stmt = gsi_stmt (*gsi);
@@ -3912,7 +3907,7 @@ handle_alloc_call (enum built_in_function bcode, gimple_stmt_iterator *gsi)
 
 static bool
 handle_builtin_memset (gimple_stmt_iterator *gsi, bool *zero_write,
-		       const vr_values *rvals)
+		       range_query *rvals)
 {
   gimple *memset_stmt = gsi_stmt (*gsi);
   tree ptr = gimple_call_arg (memset_stmt, 0);
@@ -4109,7 +4104,7 @@ static bool
 get_len_or_size (gimple *stmt, tree arg, int idx,
 		 unsigned HOST_WIDE_INT lenrng[2],
 		 unsigned HOST_WIDE_INT *size, bool *nulterm,
-		 const vr_values *rvals)
+		 range_query *rvals)
 {
   /* Invalidate.  */
   *size = HOST_WIDE_INT_M1U;
@@ -4144,6 +4139,7 @@ get_len_or_size (gimple *stmt, tree arg, int idx,
       else if (TREE_CODE (si->nonzero_chars) == SSA_NAME)
 	{
 	  wide_int min, max;
+	  // FIXME: Use range_query, you already have it.
 	  value_range_kind rng = get_range_info (si->nonzero_chars, &min, &max);
 	  if (rng == VR_RANGE)
 	    {
@@ -4222,7 +4218,7 @@ get_len_or_size (gimple *stmt, tree arg, int idx,
 static tree
 strxcmp_eqz_result (gimple *stmt, tree arg1, int idx1, tree arg2, int idx2,
 		    unsigned HOST_WIDE_INT bound, unsigned HOST_WIDE_INT len[2],
-		    unsigned HOST_WIDE_INT *psize, const vr_values *rvals)
+		    unsigned HOST_WIDE_INT *psize, range_query *rvals)
 {
   /* Determine the range the length of each string is in and whether it's
      known to be nul-terminated, or the size of the array it's stored in.  */
@@ -4379,7 +4375,7 @@ maybe_warn_pointless_strcmp (gimple *stmt, HOST_WIDE_INT bound,
    another and false otherwise.  */
 
 static bool
-handle_builtin_string_cmp (gimple_stmt_iterator *gsi, const vr_values *rvals)
+handle_builtin_string_cmp (gimple_stmt_iterator *gsi, range_query *rvals)
 {
   gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
   tree lhs = gimple_call_lhs (stmt);
@@ -4620,7 +4616,7 @@ int ssa_name_limit_t::next_ssa_name (tree ssa_name)
 static bool
 count_nonzero_bytes_addr (tree, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT,
 			  unsigned [3], bool *, bool *, bool *,
-			  const vr_values *, ssa_name_limit_t &);
+			  range_query *, ssa_name_limit_t &);
 
 /* Determines the minimum and maximum number of leading non-zero bytes
    in the representation of EXP and set LENRANGE[0] and LENRANGE[1]
@@ -4641,7 +4637,7 @@ static bool
 count_nonzero_bytes (tree exp, unsigned HOST_WIDE_INT offset,
 		     unsigned HOST_WIDE_INT nbytes,
 		     unsigned lenrange[3], bool *nulterm,
-		     bool *allnul, bool *allnonnul, const vr_values *rvals,
+		     bool *allnul, bool *allnonnul, range_query *rvals,
 		     ssa_name_limit_t &snlim)
 {
   if (TREE_CODE (exp) == SSA_NAME)
@@ -4833,7 +4829,7 @@ count_nonzero_bytes_addr (tree exp, unsigned HOST_WIDE_INT offset,
 			  unsigned HOST_WIDE_INT nbytes,
 			  unsigned lenrange[3], bool *nulterm,
 			  bool *allnul, bool *allnonnul,
-			  const vr_values *rvals, ssa_name_limit_t &snlim)
+			  range_query *rvals, ssa_name_limit_t &snlim)
 {
   int idx = get_stridx (exp);
   if (idx > 0)
@@ -4850,14 +4846,14 @@ count_nonzero_bytes_addr (tree exp, unsigned HOST_WIDE_INT offset,
       else if (si->nonzero_chars
 	       && TREE_CODE (si->nonzero_chars) == SSA_NAME)
 	{
-	  vr_values *v = CONST_CAST (vr_values *, rvals);
-	  const value_range_equiv *vr
-	    = v->get_value_range (si->nonzero_chars, si->stmt);
-	  if (vr->kind () != VR_RANGE || !range_int_cst_p (vr))
+	  value_range vr;
+	  if (!rvals->range_of_expr (vr, si->nonzero_chars, si->stmt))
+	    vr.set_varying (TREE_TYPE (si->nonzero_chars));
+	  if (vr.kind () != VR_RANGE)
 	    return false;
 
-	  minlen = tree_to_uhwi (vr->min ());
-	  maxlen = tree_to_uhwi (vr->max ());
+	  minlen = tree_to_uhwi (vr.min ());
+	  maxlen = tree_to_uhwi (vr.max ());
 	}
       else
 	return false;
@@ -4946,7 +4942,7 @@ count_nonzero_bytes_addr (tree exp, unsigned HOST_WIDE_INT offset,
 
 static bool
 count_nonzero_bytes (tree exp, unsigned lenrange[3], bool *nulterm,
-		     bool *allnul, bool *allnonnul, const vr_values *rvals)
+		     bool *allnul, bool *allnonnul, range_query *rvals)
 {
   /* Set to optimistic values so the caller doesn't have to worry about
      initializing these and to what.  On success, the function will clear
@@ -4970,7 +4966,7 @@ count_nonzero_bytes (tree exp, unsigned lenrange[3], bool *nulterm,
 
 static bool
 handle_store (gimple_stmt_iterator *gsi, bool *zero_write,
-	      const vr_values *rvals)
+	      range_query *rvals)
 {
   int idx = -1;
   strinfo *si = NULL;
@@ -5380,7 +5376,7 @@ is_char_type (tree type)
 
 static bool
 strlen_check_and_optimize_call (gimple_stmt_iterator *gsi, bool *zero_write,
-				const vr_values *rvals)
+				range_query *rvals)
 {
   gimple *stmt = gsi_stmt (*gsi);
 
@@ -5471,7 +5467,7 @@ strlen_check_and_optimize_call (gimple_stmt_iterator *gsi, bool *zero_write,
 
 static void
 handle_integral_assign (gimple_stmt_iterator *gsi, bool *cleanup_eh,
-			const vr_values *rvals)
+			range_query *rvals)
 {
   gimple *stmt = gsi_stmt (*gsi);
   tree lhs = gimple_assign_lhs (stmt);
@@ -5563,6 +5559,7 @@ handle_integral_assign (gimple_stmt_iterator *gsi, bool *cleanup_eh,
 		  wide_int min, max;
 		  signop sign = TYPE_SIGN (lhs_type);
 		  int prec = TYPE_PRECISION (lhs_type);
+		  // FIXME: Use range_query, you already have it.
 		  value_range_kind vr = get_range_info (lhs, &min, &max);
 		  if (vr == VR_VARYING
 		      || (vr == VR_RANGE
@@ -5615,7 +5612,7 @@ handle_integral_assign (gimple_stmt_iterator *gsi, bool *cleanup_eh,
 
 static bool
 check_and_optimize_stmt (gimple_stmt_iterator *gsi, bool *cleanup_eh,
-			 const vr_values *rvals)
+			 range_query *rvals)
 {
   gimple *stmt = gsi_stmt (*gsi);
 
diff --git a/gcc/tree-ssa-strlen.h b/gcc/tree-ssa-strlen.h
index 0e9c7143308..225f64b1630 100644
--- a/gcc/tree-ssa-strlen.h
+++ b/gcc/tree-ssa-strlen.h
@@ -25,14 +25,14 @@ extern bool is_strlen_related_p (tree, tree);
 extern bool maybe_diag_stxncpy_trunc (gimple_stmt_iterator, tree, tree);
 extern tree set_strlen_range (tree, wide_int, wide_int, tree = NULL_TREE);
 
-class vr_values;
-extern tree get_range (tree, gimple *, wide_int[2], const vr_values * = NULL);
+extern tree get_range (tree, gimple *, wide_int[2],
+		       class range_query * = NULL);
 
 struct c_strlen_data;
 extern void get_range_strlen_dynamic (tree, gimple *, c_strlen_data *,
-				      const vr_values *);
+				      class range_query *);
 
 /* APIs internal to strlen pass.  Defined in gimple-ssa-sprintf.c.  */
-extern bool handle_printf_call (gimple_stmt_iterator *,  const vr_values *);
+extern bool handle_printf_call (gimple_stmt_iterator *,  class range_query *);
 
 #endif   // GCC_TREE_SSA_STRLEN_H


More information about the Gcc-cvs mailing list