analyzer: introduce byte_range and use to simplify dumps

gcc/analyzer/ChangeLog:
	* analyzer.h (byte_offset_t): New typedef.
	* store.cc (bit_range::dump_to_pp): Dump as a byte range if
	possible.
	(bit_range::as_byte_range): New.
	(byte_range::dump_to_pp): New.
	* store.h (class byte_range): New forward decl.
	(struct bit_range): Add comment.
	(bit_range::as_byte_range): New decl.
	(struct byte_range): New.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
This commit is contained in:
David Malcolm 2021-06-28 19:18:06 -04:00
parent 40c64c9ea5
commit 7c6b354b92
3 changed files with 74 additions and 6 deletions

View File

@ -142,6 +142,7 @@ public:
typedef offset_int bit_offset_t;
typedef offset_int bit_size_t;
typedef offset_int byte_offset_t;
typedef offset_int byte_size_t;
extern bool int_size_in_bits (const_tree type, bit_size_t *out);

View File

@ -241,12 +241,18 @@ binding_key::cmp (const binding_key *k1, const binding_key *k2)
void
bit_range::dump_to_pp (pretty_printer *pp) const
{
pp_string (pp, "start: ");
pp_wide_int (pp, m_start_bit_offset, SIGNED);
pp_string (pp, ", size: ");
pp_wide_int (pp, m_size_in_bits, SIGNED);
pp_string (pp, ", next: ");
pp_wide_int (pp, get_next_bit_offset (), SIGNED);
byte_range bytes (0, 0);
if (as_byte_range (&bytes))
bytes.dump_to_pp (pp);
else
{
pp_string (pp, "start: ");
pp_wide_int (pp, m_start_bit_offset, SIGNED);
pp_string (pp, ", size: ");
pp_wide_int (pp, m_size_in_bits, SIGNED);
pp_string (pp, ", next: ");
pp_wide_int (pp, get_next_bit_offset (), SIGNED);
}
}
/* Dump this object to stderr. */
@ -329,6 +335,42 @@ bit_range::from_mask (unsigned HOST_WIDE_INT mask, bit_range *out)
return true;
}
/* Attempt to convert this bit_range to a byte_range.
Return true if it is possible, writing the result to *OUT.
Otherwise return false. */
bool
bit_range::as_byte_range (byte_range *out) const
{
if (m_start_bit_offset % BITS_PER_UNIT == 0
&& m_size_in_bits % BITS_PER_UNIT == 0)
{
out->m_start_byte_offset = m_start_bit_offset / BITS_PER_UNIT;
out->m_size_in_bytes = m_size_in_bits / BITS_PER_UNIT;
return true;
}
return false;
}
/* Dump this object to PP. */
void
byte_range::dump_to_pp (pretty_printer *pp) const
{
if (m_size_in_bytes == 1)
{
pp_string (pp, "byte ");
pp_wide_int (pp, m_start_byte_offset, SIGNED);
}
else
{
pp_string (pp, "bytes ");
pp_wide_int (pp, m_start_byte_offset, SIGNED);
pp_string (pp, "-");
pp_wide_int (pp, get_last_byte_offset (), SIGNED);
}
}
/* class concrete_binding : public binding_key. */
/* Implementation of binding_key::dump_to_pp vfunc for concrete_binding. */

View File

@ -196,6 +196,7 @@ private:
hash_set<const svalue *> m_mutable_at_unknown_call_svals;
};
class byte_range;
class concrete_binding;
/* An enum for discriminating between "direct" vs "default" levels of
@ -267,6 +268,8 @@ private:
enum binding_kind m_kind;
};
/* A concrete range of bits. */
struct bit_range
{
bit_range (bit_offset_t start_bit_offset, bit_size_t size_in_bits)
@ -308,10 +311,32 @@ struct bit_range
static bool from_mask (unsigned HOST_WIDE_INT mask, bit_range *out);
bool as_byte_range (byte_range *out) const;
bit_offset_t m_start_bit_offset;
bit_size_t m_size_in_bits;
};
/* A concrete range of bytes. */
struct byte_range
{
byte_range (byte_offset_t start_byte_offset, byte_size_t size_in_bytes)
: m_start_byte_offset (start_byte_offset),
m_size_in_bytes (size_in_bytes)
{}
void dump_to_pp (pretty_printer *pp) const;
byte_offset_t get_last_byte_offset () const
{
return m_start_byte_offset + m_size_in_bytes - 1;
}
byte_offset_t m_start_byte_offset;
byte_size_t m_size_in_bytes;
};
/* Concrete subclass of binding_key, for describing a concrete range of
bits within the binding_map (e.g. "bits 8-15"). */