Convert sprintf/strlen passes to value query class.
authorAldy Hernandez <aldyh@redhat.com>
Thu, 17 Sep 2020 07:34:03 +0000 (09:34 +0200)
committerAldy Hernandez <aldyh@redhat.com>
Thu, 1 Oct 2020 15:11:17 +0000 (17:11 +0200)
gcc/ChangeLog:

* builtins.c (compute_objsize): Replace vr_values with range_query.
(get_range): Same.
(gimple_call_alloc_size): Same.
* builtins.h (class vr_values):  Remove.
(gimple_call_alloc_size): Replace vr_values with range_query.
* gimple-ssa-sprintf.c (get_int_range): Same.
(struct directive): Pass gimple context to fmtfunc callback.
(directive::set_width): Replace inline with out-of-line version.
(directive::set_precision): Same.
(format_none): New gimple argument.
(format_percent): New gimple argument.
(format_integer): New gimple argument.
(format_floating): New gimple argument.
(get_string_length): Use range_query API.
(format_character): New gimple argument.
(format_string): New gimple argument.
(format_plain): New gimple argument.
(format_directive): New gimple argument.
(parse_directive): Replace vr_values with range_query.
(compute_format_length): Same.
(handle_printf_call): Same.  Adjust for range_query API.
* tree-ssa-strlen.c (get_range): Same.
(compare_nonzero_chars): Same.
(get_addr_stridx) Replace vr_values with range_query.
(get_stridx): Same.
(dump_strlen_info): Same.
(get_range_strlen_dynamic): Adjust for range_query API.
(set_strlen_range): Same
(maybe_warn_overflow): Replace vr_values with range_query.
(handle_builtin_strcpy): Same.
(maybe_diag_stxncpy_trunc): Add FIXME comment.
(handle_builtin_memcpy): Replace vr_values with range_query.
(handle_builtin_memset): Same.
(get_len_or_size): Same.
(strxcmp_eqz_result): Same.
(handle_builtin_string_cmp): Same.
(count_nonzero_bytes_addr): Same, plus adjust for range_query API.
(count_nonzero_bytes): Replace vr_values with range_query.
(handle_store): Same.
(strlen_check_and_optimize_call): Same.
(handle_integral_assign): Same.
(check_and_optimize_stmt): Same.
* tree-ssa-strlen.h (class vr_values): Remove.
(get_range): Replace vr_values with range_query.
(get_range_strlen_dynamic): Same.
(handle_printf_call): Same.

gcc/builtins.c
gcc/builtins.h
gcc/gimple-ssa-sprintf.c
gcc/tree-ssa-strlen.c
gcc/tree-ssa-strlen.h

index 8f2662bb7284775a1cb44f8ff15fe80a60df2e05..f91266e42405f4799ec66bc4bc9b39072075c37f 100644 (file)
@@ -183,7 +183,8 @@ static void maybe_emit_chk_warning (tree, enum built_in_function);
 static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
 static void maybe_emit_free_warning (tree);
 static tree fold_builtin_object_size (tree, tree);
-static bool get_range (tree, signop, offset_int[2], const vr_values * = NULL);
+static bool get_range (tree, gimple *, signop, offset_int[2],
+                      range_query * = NULL);
 static bool check_read_access (tree, tree, tree = NULL_TREE, int = 1);
 
 unsigned HOST_WIDE_INT target_newline;
@@ -4152,7 +4153,7 @@ check_read_access (tree exp, tree src, tree bound /* = NULL_TREE */,
 
 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;
@@ -4206,7 +4207,7 @@ gimple_call_alloc_size (gimple *stmt, wide_int rng1[2] /* = NULL */,
 
   const int prec = ADDR_MAX_PRECISION;
   const tree size_max = TYPE_MAX_VALUE (sizetype);
-  if (!get_range (size, rng1, rvals))
+  if (!get_range (size, stmt, rng1, rvals))
     {
       /* Use the full non-negative range on failure.  */
       rng1[0] = wi::zero (prec);
@@ -4220,7 +4221,7 @@ gimple_call_alloc_size (gimple *stmt, wide_int rng1[2] /* = NULL */,
      of the upper bounds as a constant.  Ignore anti-ranges.  */
   tree n = argidx2 < nargs ? gimple_call_arg (stmt, argidx2) : integer_one_node;
   wide_int rng2[2];
-  if (!get_range (n, rng2, rvals))
+         if (!get_range (n, stmt, rng2, rvals))
     {
       /* As above, use the full non-negative range on failure.  */
       rng2[0] = wi::zero (prec);
@@ -4252,8 +4253,7 @@ gimple_call_alloc_size (gimple *stmt, wide_int rng1[2] /* = NULL */,
    Return the function parameter on success and null otherwise.  */
 
 tree
-gimple_parm_array_size (tree ptr, wide_int rng[2],
-                       const vr_values * /* = NULL */)
+gimple_parm_array_size (tree ptr, wide_int rng[2], range_query * /* = NULL */)
 {
   /* For a function argument try to determine the byte size of the array
      from the current function declaratation (e.g., attribute access or
@@ -4305,11 +4305,11 @@ gimple_parm_array_size (tree ptr, wide_int rng[2],
    result but accepts offset_int instead.  */
 
 static bool
-get_range (tree x, signop sgn, offset_int r[2],
-          const vr_values *rvals /* = NULL */)
+get_range (tree x, gimple *stmt, signop sgn, offset_int r[2],
+          range_query *rvals /* = NULL */)
 {
   wide_int wr[2];
-  if (!get_range (x, wr, rvals))
+  if (!get_range (x, stmt, wr, rvals))
     return false;
 
   r[0] = offset_int::from (wr[0], sgn);
@@ -4333,7 +4333,7 @@ get_range (tree x, 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)
@@ -4431,7 +4431,7 @@ compute_objsize (tree ptr, int ostype, access_ref *pref,
 
       offset_int orng[2];
       tree off = TREE_OPERAND (ptr, 1);
-      if (!get_range (off, SIGNED, orng, rvals))
+      if (!get_range (off, NULL, SIGNED, orng, rvals))
        /* Fail unless the size of the object is zero.  */
        return pref->sizrng[0] == 0 && pref->sizrng[0] == pref->sizrng[1];
 
@@ -4527,7 +4527,7 @@ compute_objsize (tree ptr, int ostype, access_ref *pref,
             offset to the maximum.  */
          offset_int orng[2];
          tree off = gimple_assign_rhs2 (stmt);
-         if (!get_range (off, SIGNED, orng, rvals))
+         if (!get_range (off, stmt, SIGNED, orng, rvals))
            {
              orng[0] = wi::to_offset (TYPE_MIN_VALUE (ptrdiff_type_node));
              orng[1] = wi::to_offset (TYPE_MAX_VALUE (ptrdiff_type_node));
@@ -4551,7 +4551,7 @@ compute_objsize (tree ptr, int ostype, access_ref *pref,
       && !array_at_struct_end_p (ptr))
     {
       if (tree size = TYPE_SIZE_UNIT (type))
-       return get_range (size, UNSIGNED, pref->sizrng, rvals);
+       return get_range (size, NULL, UNSIGNED, pref->sizrng, rvals);
     }
 
   return false;
@@ -4562,7 +4562,7 @@ compute_objsize (tree ptr, int ostype, access_ref *pref,
 
 tree
 compute_objsize (tree ptr, int ostype, access_ref *pref,
-                const vr_values *rvals /* = NULL */)
+                range_query *rvals /* = NULL */)
 {
   bitmap visited = NULL;
 
@@ -4603,7 +4603,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.  */
index 8136b768750bd60ed35ad298f2ca752b0512d453..504c618b851ff23df3f7b693a93fef40d17e1fb1 100644 (file)
@@ -195,13 +195,13 @@ struct access_data
   access_mode mode;
 };
 
-class vr_values;
+class range_query;
 extern tree gimple_call_alloc_size (gimple *, wide_int[2] = NULL,
-                                   const vr_values * = NULL);
-extern tree gimple_parm_array_size (tree, wide_int[2], const vr_values * = NULL);
+                                   range_query * = NULL);
+extern tree gimple_parm_array_size (tree, wide_int[2], range_query * = NULL);
 extern tree compute_objsize (tree, int, tree * = NULL, tree * = NULL,
-                            const vr_values * = NULL);
-extern tree compute_objsize (tree, int, access_ref *, const vr_values * = NULL);
+                            range_query * = NULL);
+extern tree compute_objsize (tree, int, access_ref *, range_query * = NULL);
 
 extern bool check_access (tree, tree, tree, tree, tree, access_mode,
                          const access_data * = NULL);
index 70b031fe7b94c656fef11a00f94598eb4fbe4554..fff034fac4ddeb87f8cdf64f30994f876878e0d8 100644 (file)
@@ -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) (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 (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 (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,10 @@ 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;
+         query->range_of_expr (vr, arg, stmt);
 
-         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 +1087,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 +1110,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 +1196,7 @@ 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 (const directive &dir, tree arg, range_query *query)
 {
   tree intmax_type_node;
   tree uintmax_type_node;
@@ -1372,13 +1379,13 @@ 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;
+      query->range_of_expr (vr, arg, dir.info->callstmt);
 
-      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 +1411,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 (dir, arg, query);
                }
 
              if (code == NOP_EXPR)
@@ -1449,16 +1456,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 (dir, argmin, query).range.min;
+      res.range.max = format_integer (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 (dir, argmax, query).range.min;
+      res.range.max = format_integer (dir, argmin, query).range.max;
     }
   else
     {
@@ -1467,11 +1474,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 (dir, argmin, query).range.max;
       unsigned HOST_WIDE_INT max2
-       = format_integer (dir, argmax, vr_values).range.max;
+       = format_integer (dir, argmax, query).range.max;
       res.range.min
-       = format_integer (dir, integer_zero_node, vr_values).range.min;
+       = format_integer (dir, integer_zero_node, query).range.min;
       res.range.max = MAX (max1, max2);
     }
 
@@ -1820,7 +1827,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 (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
@@ -2014,7 +2021,8 @@ format_floating (const directive &dir, tree arg, const vr_values *)
    Used by the format_string function below.  */
 
 static fmtresult
-get_string_length (tree str, unsigned eltsize, const vr_values *vr)
+get_string_length (tree str, gimple *stmt, unsigned eltsize,
+                  range_query *query)
 {
   if (!str)
     return fmtresult ();
@@ -2025,7 +2033,7 @@ get_string_length (tree str, unsigned eltsize, const vr_values *vr)
   c_strlen_data lendata = { };
   lendata.maxbound = str;
   if (eltsize == 1)
-    get_range_strlen_dynamic (str, &lendata, vr);
+    get_range_strlen_dynamic (str, stmt, &lendata, query);
   else
     {
       /* Determine the length of the shortest and longest string referenced
@@ -2122,7 +2130,7 @@ get_string_length (tree str, unsigned eltsize, const vr_values *vr)
    vsprinf).  */
 
 static fmtresult
-format_character (const directive &dir, tree arg, const vr_values *vr_values)
+format_character (const directive &dir, tree arg, range_query *query)
 {
   fmtresult res;
 
@@ -2135,7 +2143,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, dir.info->callstmt, &min, &max, false, 0, query))
        {
          if (min == 0 && max == 0)
            {
@@ -2433,7 +2441,7 @@ 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 (const directive &dir, tree arg, range_query *query)
 {
   fmtresult res;
 
@@ -2462,7 +2470,7 @@ format_string (const directive &dir, tree arg, const vr_values *vr_values)
       gcc_checking_assert (count_by == 2 || count_by == 4);
     }
 
-  fmtresult slen = get_string_length (arg, count_by, vr_values);
+  fmtresult slen = get_string_length (arg, dir.info->callstmt, count_by, query);
   if (slen.range.min == slen.range.max
       && slen.range.min < HOST_WIDE_INT_MAX)
     {
@@ -2634,7 +2642,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 (const directive &dir, tree, range_query *)
 {
   fmtresult res (dir.len);
   return res;
@@ -3030,7 +3038,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.  */
@@ -3055,7 +3063,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 (dir, dir.arg, query);
 
   /* Record whether the output of all directives is known to be
      bounded by some maximum, implying that their arguments are
@@ -3386,7 +3394,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;
@@ -3711,7 +3719,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]
@@ -3744,7 +3752,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]
@@ -3958,7 +3966,7 @@ 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)
     {
@@ -3995,10 +4003,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
@@ -4288,7 +4296,7 @@ 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 ();
 
@@ -4557,14 +4565,14 @@ 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;
+         query->range_of_expr (vr, size, info.callstmt);
 
-         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;
@@ -4675,7 +4683,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);
 
index 9907cc0c8242031520d5ab25cd9c8ca244412da3..f4d1c5ca25625713651ba1f44faf64030f28b7f9 100644 (file)
@@ -200,7 +200,8 @@ static void handle_builtin_stxncpy_strncat (bool, gimple_stmt_iterator *);
    to determine the range, otherwise get_range_info.  */
 
 tree
-get_range (tree val, wide_int minmax[2], const vr_values *rvals /* = NULL */)
+get_range (tree val, gimple *stmt, wide_int minmax[2],
+          range_query *rvals /* = NULL */)
 {
   if (TREE_CODE (val) == INTEGER_CST)
     {
@@ -211,21 +212,17 @@ get_range (tree val, wide_int minmax[2], const vr_values *rvals /* = NULL */)
   if (TREE_CODE (val) != SSA_NAME)
     return NULL_TREE;
 
-  if (rvals)
-    {
-      /* 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));
-      value_range_kind rng = vr->kind ();
-      if (rng != VR_RANGE || !range_int_cst_p (vr))
+  if (rvals && stmt)
+    {
+      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;
     }
 
@@ -263,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;
@@ -274,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));
-
-  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;
@@ -332,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;
@@ -392,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));
@@ -474,7 +470,7 @@ get_stridx (tree exp, wide_int offrng[2] = NULL, const vr_values *rvals = NULL)
                       return the index corresponding to the SSA_NAME.
                       Do this irrespective of the whether the offset
                       is known.  */
-                   if (get_range (off, offrng, rvals))
+                   if (get_range (off, def_stmt, offrng, rvals))
                      {
                        /* When the offset range is known, increment it
                           it by the constant offset computed in prior
@@ -864,11 +860,11 @@ get_string_length (strinfo *si)
 }
 
 /* Dump strlen data to FP for statement STMT.  When non-null, RVALS
-   points to EVRP info and is used to dump strlen range for non-constant
-   results.  */
+   points to the valuation engine used to calculate ranges, and is
+   used to dump strlen range for non-constant 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)
     {
@@ -909,14 +905,14 @@ 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);
-                         rng = vr->kind ();
-                         if (range_int_cst_p (vr))
+                         value_range vr;
+                         rvals->range_of_expr (vr, si->nonzero_chars,
+                                               si->stmt);
+                         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;
@@ -1004,13 +1000,14 @@ dump_strlen_info (FILE *fp, gimple *stmt, const vr_values *rvals)
 
 /* Attempt to determine the length of the string SRC.  On success, store
    the length in *PDATA and return true.  Otherwise, return false.
-   VISITED is a bitmap of visited PHI nodes.  RVALS points to EVRP info
-   and PSSA_DEF_MAX to an SSA_NAME assignment limit used to prevent runaway
-   recursion.  */
+   VISITED is a bitmap of visited PHI nodes.  RVALS points to the valuation
+   engine used to calculate ranges.  PSSA_DEF_MAX to an SSA_NAME
+   assignment limit used to prevent runaway recursion.  */
 
 static bool
-get_range_strlen_dynamic (tree src, c_strlen_data *pdata, bitmap *visited,
-                         const vr_values *rvals, unsigned *pssa_def_max)
+get_range_strlen_dynamic (tree src, gimple *stmt,
+                         c_strlen_data *pdata, bitmap *visited,
+                         range_query *rvals, unsigned *pssa_def_max)
 {
   int idx = get_stridx (src);
   if (!idx)
@@ -1042,8 +1039,8 @@ get_range_strlen_dynamic (tree src, c_strlen_data *pdata, bitmap *visited,
                    continue;
 
                  c_strlen_data argdata = { };
-                 if (get_range_strlen_dynamic (arg, &argdata, visited, rvals,
-                                               pssa_def_max))
+                 if (get_range_strlen_dynamic (arg, phi, &argdata, visited,
+                                               rvals, pssa_def_max))
                    {
                      /* Set the DECL of an unterminated array this argument
                         refers to if one hasn't been found yet.  */
@@ -1110,14 +1107,12 @@ get_range_strlen_dynamic (tree src, c_strlen_data *pdata, bitmap *visited,
            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);
-             if (vr->kind () == VR_RANGE
-                 && range_int_cst_p (vr))
+             value_range vr;
+             rvals->range_of_expr (vr, si->nonzero_chars, si->stmt);
+             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);
@@ -1156,14 +1151,12 @@ get_range_strlen_dynamic (tree src, c_strlen_data *pdata, bitmap *visited,
        }
       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);
-         if (vr->kind () == VR_RANGE
-             && range_int_cst_p (vr))
+         value_range vr;
+         rvals->range_of_expr (vr, si->nonzero_chars, stmt);
+         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
@@ -1198,17 +1191,17 @@ get_range_strlen_dynamic (tree src, c_strlen_data *pdata, bitmap *visited,
    Try to obtain the range of the lengths of the string(s) referenced
    by SRC, or the size of the largest array SRC refers to if the range
    of lengths cannot be determined, and store all in *PDATA.  RVALS
-   points to EVRP info.  */
+   points to the valuation engine used to calculate ranges.  */
 
 void
-get_range_strlen_dynamic (tree src, c_strlen_data *pdata,
-                         const vr_values *rvals)
+get_range_strlen_dynamic (tree src, gimple *stmt, c_strlen_data *pdata,
+                         range_query *rvals)
 {
   bitmap visited = NULL;
   tree maxbound = pdata->maxbound;
 
   unsigned limit = param_ssa_name_def_chain_limit;
-  if (!get_range_strlen_dynamic (src, pdata, &visited, rvals, &limit))
+  if (!get_range_strlen_dynamic (src, stmt, pdata, &visited, rvals, &limit))
     {
       /* On failure extend the length range to an impossible maximum
         (a valid MAXLEN must be less than PTRDIFF_MAX - 1).  Other
@@ -1803,6 +1796,7 @@ set_strlen_range (tree lhs, wide_int min, wide_int max,
       else if (TREE_CODE (bound) == SSA_NAME)
        {
          wide_int minbound, maxbound;
+         // FIXME: Use range_query instead of global ranges.
          value_range_kind rng = get_range_info (bound, &minbound, &maxbound);
          if (rng == VR_RANGE)
            {
@@ -1907,7 +1901,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)
 {
@@ -1959,7 +1953,7 @@ maybe_warn_overflow (gimple *stmt, tree len,
          tree off = TREE_OPERAND (ref, 1);
          ref = TREE_OPERAND (ref, 0);
          wide_int rng[2];
-         if (get_range (off, rng, rvals))
+         if (get_range (off, stmt, rng, rvals))
            {
              /* Convert offsets to the maximum precision.  */
              offrng[0] = widest_int::from (rng[0], SIGNED);
@@ -1977,7 +1971,7 @@ maybe_warn_overflow (gimple *stmt, tree len,
          tree mem_off = TREE_OPERAND (ref, 1);
          ref = TREE_OPERAND (ref, 0);
          wide_int rng[2];
-         if (get_range (mem_off, rng, rvals))
+         if (get_range (mem_off, stmt, rng, rvals))
            {
              offrng[0] += widest_int::from (rng[0], SIGNED);
              offrng[1] += widest_int::from (rng[1], SIGNED);
@@ -2049,7 +2043,7 @@ maybe_warn_overflow (gimple *stmt, tree len,
            }
 
          wide_int rng[2];
-         if (get_range (destsize, rng, rvals))
+         if (get_range (destsize, stmt, rng, rvals))
            {
              sizrng[0] = widest_int::from (rng[0], UNSIGNED);
              sizrng[1] = widest_int::from (rng[1], UNSIGNED);
@@ -2080,7 +2074,7 @@ maybe_warn_overflow (gimple *stmt, tree len,
     return;
 
   wide_int rng[2];
-  if (!get_range (len, rng, rvals))
+  if (!get_range (len, stmt, rng, rvals))
     return;
 
   widest_int lenrng[2] =
@@ -2231,7 +2225,7 @@ maybe_warn_overflow (gimple *stmt, tree len,
   if (destoff)
     {
       wide_int rng[2];
-      if (get_range (destoff, rng))
+      if (get_range (destoff, stmt, rng))
        {
          offrng[0] = widest_int::from (rng[0], SIGNED);
          offrng[1] = widest_int::from (rng[1], SIGNED);
@@ -2339,7 +2333,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,
@@ -2642,7 +2636,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;
@@ -3036,6 +3030,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: Use range_query instead of global ranges.
       enum value_range_kind rng = get_range_info (cnt, cntrange, cntrange + 1);
       if (rng == VR_RANGE)
        ;
@@ -3444,7 +3439,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);
@@ -3909,7 +3904,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);
@@ -4103,9 +4098,10 @@ handle_builtin_memcmp (gimple_stmt_iterator *gsi)
    determine range information. Returns true on success.  */
 
 static bool
-get_len_or_size (tree arg, int idx, unsigned HOST_WIDE_INT lenrng[2],
+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;
@@ -4140,6 +4136,7 @@ get_len_or_size (tree arg, int idx, unsigned HOST_WIDE_INT lenrng[2],
       else if (TREE_CODE (si->nonzero_chars) == SSA_NAME)
        {
          wide_int min, max;
+         // FIXME: Use range_query instead of global ranges.
          value_range_kind rng = get_range_info (si->nonzero_chars, &min, &max);
          if (rng == VR_RANGE)
            {
@@ -4158,7 +4155,7 @@ get_len_or_size (tree arg, int idx, unsigned HOST_WIDE_INT lenrng[2],
   /* Set MAXBOUND to an arbitrary non-null non-integer node as a request
      to have it set to the length of the longest string in a PHI.  */
   lendata.maxbound = arg;
-  get_range_strlen_dynamic (arg, &lendata, rvals);
+  get_range_strlen_dynamic (arg, stmt, &lendata, rvals);
 
   unsigned HOST_WIDE_INT maxbound = HOST_WIDE_INT_M1U;
   if (tree_fits_uhwi_p (lendata.maxbound)
@@ -4216,17 +4213,17 @@ get_len_or_size (tree arg, int idx, unsigned HOST_WIDE_INT lenrng[2],
    Otherwise return null.  */
 
 static tree
-strxcmp_eqz_result (tree arg1, int idx1, tree arg2, int idx2,
+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.  */
   bool nul1, nul2;
   unsigned HOST_WIDE_INT siz1, siz2;
   unsigned HOST_WIDE_INT len1rng[2], len2rng[2];
-  if (!get_len_or_size (arg1, idx1, len1rng, &siz1, &nul1, rvals)
-      || !get_len_or_size (arg2, idx2, len2rng, &siz2, &nul2, rvals))
+  if (!get_len_or_size (stmt, arg1, idx1, len1rng, &siz1, &nul1, rvals)
+      || !get_len_or_size (stmt, arg2, idx2, len2rng, &siz2, &nul2, rvals))
     return NULL_TREE;
 
   /* BOUND is set to HWI_M1U for strcmp and less to strncmp, and LENiRNG
@@ -4375,7 +4372,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);
@@ -4420,7 +4417,7 @@ handle_builtin_string_cmp (gimple_stmt_iterator *gsi, const vr_values *rvals)
     /* Try to determine if the two strings are either definitely equal
        or definitely unequal and if so, either fold the result to zero
        (when equal) or set the range of the result to ~[0, 0] otherwise.  */
-    if (tree eqz = strxcmp_eqz_result (arg1, idx1, arg2, idx2, bound,
+    if (tree eqz = strxcmp_eqz_result (stmt, arg1, idx1, arg2, idx2, bound,
                                       len, &siz, rvals))
       {
        if (integer_zerop (eqz))
@@ -4457,8 +4454,9 @@ handle_builtin_string_cmp (gimple_stmt_iterator *gsi, const vr_values *rvals)
     unsigned HOST_WIDE_INT arsz1, arsz2;
     bool nulterm[2];
 
-    if (!get_len_or_size (arg1, idx1, len1rng, &arsz1, nulterm, rvals)
-       || !get_len_or_size (arg2, idx2, len2rng, &arsz2, nulterm + 1, rvals))
+    if (!get_len_or_size (stmt, arg1, idx1, len1rng, &arsz1, nulterm, rvals)
+       || !get_len_or_size (stmt, arg2, idx2, len2rng, &arsz2, nulterm + 1,
+                            rvals))
       return false;
 
     if (len1rng[0] == len1rng[1] && len1rng[0] < HOST_WIDE_INT_MAX)
@@ -4623,7 +4621,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]
@@ -4644,7 +4642,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)
@@ -4836,7 +4834,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)
@@ -4853,13 +4851,13 @@ 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);
-         if (vr->kind () != VR_RANGE || !range_int_cst_p (vr))
+         value_range vr;
+         rvals->range_of_expr (vr, si->nonzero_chars, si->stmt);
+         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;
@@ -4948,7 +4946,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
@@ -4972,7 +4970,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;
@@ -5382,7 +5380,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);
 
@@ -5473,7 +5471,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);
@@ -5565,6 +5563,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 instead of global ranges.
                  value_range_kind vr = get_range_info (lhs, &min, &max);
                  if (vr == VR_VARYING
                      || (vr == VR_RANGE
@@ -5617,7 +5616,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);
 
index a11c4d579a1747fa9d16316c1bf21c6660042e5d..225f64b1630ba0c6b8349cd2a3c6d5da14bf4be3 100644 (file)
@@ -25,13 +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, 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 , c_strlen_data *, const vr_values *);
+extern void get_range_strlen_dynamic (tree, gimple *, c_strlen_data *,
+                                     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