On Sat, Nov 12, 2022 at 3:47 PM Bernhard Reutner-Fischer via Gcc-patches <gcc-patc...@gcc.gnu.org> wrote: > > gcc/ChangeLog: > > * value-range.cc (get_bound_with_infinite_markers): New static helper. > (irange::as_string): New definition. > * value-range.h: New declaration. > > --- > Provide means to print a value range to a newly allocated buffer. > The caller is responsible to free() the allocated memory. > > Bootstrapped and regtested on x86_86-unknown-linux with no regressions. > Ok for trunk? > > Cc: Andrew MacLeod <amacl...@redhat.com> > Cc: Aldy Hernandez <al...@redhat.com> > --- > gcc/value-range.cc | 56 ++++++++++++++++++++++++++++++++++++++++++++++ > gcc/value-range.h | 3 +++ > 2 files changed, 59 insertions(+) > > diff --git a/gcc/value-range.cc b/gcc/value-range.cc > index a855aaf626c..51cd9a38d90 100644 > --- a/gcc/value-range.cc > +++ b/gcc/value-range.cc > @@ -3099,6 +3099,62 @@ debug (const value_range &vr) > fprintf (stderr, "\n"); > } > > +/* Helper for irange::as_string(). Print a bound to an allocated buffer. */ > +static char *
Can we start using std::string instead of char* here? > +get_bound_with_infinite_markers (tree bound) > +{ > + tree type = TREE_TYPE (bound); > + wide_int type_min = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN > (type)); > + wide_int type_max = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN > (type)); > + > + if (INTEGRAL_TYPE_P (type) > + && !TYPE_UNSIGNED (type) > + && TREE_CODE (bound) == INTEGER_CST > + && wi::to_wide (bound) == type_min > + && TYPE_PRECISION (type) != 1) > + return xstrdup ("-INF"); > + else if (TREE_CODE (bound) == INTEGER_CST > + && wi::to_wide (bound) == type_max > + && TYPE_PRECISION (type) != 1) > + return xstrdup ("+INF"); > + else > + return print_generic_expr_to_str (bound); No reason to do xstrdup any more either. > +} > + > + > +/* Return an irange as string. Return NULL on failure, an allocated > + string on success. */ > +char * Likewise. Thanks, Andrew Pinski > +irange::as_string () > +{ > + char *ret = NULL; This becomes std::string ret; > + if (undefined_p() || varying_p () || m_num_ranges == 0) > + return ret; > + > + for (unsigned i = 0; i < m_num_ranges; ++i) > + { > + tree lb = m_base[i * 2]; > + tree ub = m_base[i * 2 + 1]; > + /* Construct [lower_bound,upper_bound]. */ > + char *lbs = get_bound_with_infinite_markers (lb); > + char *ubs = get_bound_with_infinite_markers (ub); > + /* Paranoia mode */ > + if (!lbs) > + lbs = xstrdup (""); > + if (!ubs) > + ubs = xstrdup (""); > + > + if (ret) > + ret = reconcat (ret, ret, "[", lbs, ",", ubs, "]", NULL); > + else > + ret = concat ("[", lbs, ",", ubs, "]", NULL); > + > + free (lbs); > + free (ubs); > + } > + return ret; > +} > + > /* Create two value-ranges in *VR0 and *VR1 from the anti-range *AR > so that *VR0 U *VR1 == *AR. Returns true if that is possible, > false otherwise. If *AR can be represented with a single range > diff --git a/gcc/value-range.h b/gcc/value-range.h > index c87734dd8cd..76242e4bf45 100644 > --- a/gcc/value-range.h > +++ b/gcc/value-range.h > @@ -160,6 +160,9 @@ public: > wide_int get_nonzero_bits () const; > void set_nonzero_bits (const wide_int_ref &bits); > > + // For diagnostics. > + char *as_string (); > + > // Deprecated legacy public methods. > tree min () const; // DEPRECATED > tree max () const; // DEPRECATED > -- > 2.38.1 >