blob: c0e3f860df9e2c38e864e977fd79a8d7963dccc9 [file]
/* Unit-safe concrete ranges of values (e.g. "bits 16-31", "bytes 0-1023").
Copyright (C) 2026 Free Software Foundation, Inc.
Contributed by David Malcolm <dmalcolm@redhat.com>.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_ANALYZER_CONCRETE_RANGES_H
#define GCC_ANALYZER_CONCRETE_RANGES_H
#include "analyzer/integer-with-unit.h"
namespace ana {
namespace concrete {
/* Concrete ranges of bits or bytes (or unitless). */
template<typename ConcreteValueType>
class range
{
public:
range () = default;
range (ConcreteValueType start_offset,
ConcreteValueType size)
: m_start_offset (start_offset),
m_size (size)
{
}
void
dump () const;
void
dump_to_pp (pretty_printer *pp) const;
void
dump_to_pp_pretty (pretty_printer *pp) const;
ConcreteValueType
get_start_offset () const { return m_start_offset; };
ConcreteValueType
get_size () const { return m_size; }
ConcreteValueType
get_last_offset () const
{
return get_next_offset () - ConcreteValueType (1);
}
ConcreteValueType
get_next_offset () const { return m_start_offset + m_size; }
bool
contains_p (ConcreteValueType offset) const
{
return (offset >= get_start_offset ()
&& offset < get_next_offset ());
}
bool
intersects_p (const range &other, range *out = nullptr) const;
bool
exceeds_p (ConcreteValueType offset,
range<ConcreteValueType> *out) const;
bool
falls_short_of_p (ConcreteValueType offset,
range<ConcreteValueType> *out) const;
bool
operator== (const range<ConcreteValueType> &other) const
{
return (m_start_offset == other.m_start_offset
&& m_size == other.m_size);
}
static int
cmp (const range<ConcreteValueType> &lhs,
const range<ConcreteValueType> &rhs);
bool
operator< (const range<ConcreteValueType> &other) const
{
return cmp (*this, other) < 0;
}
std::unique_ptr<json::object>
to_json () const;
std::unique_ptr<diagnostics::markup::node>
make_markup_node () const;
private:
ConcreteValueType m_start_offset;
ConcreteValueType m_size;
};
} // namespace ana::concrete
using concrete_bit_range = concrete::range<integer_with_unit<units::bit>>;
using concrete_byte_range = concrete::range<integer_with_unit<units::byte>>;
inline concrete_bit_range
bits_from_bytes (concrete_byte_range bytes)
{
return concrete_bit_range (bits_from_bytes (bytes.get_start_offset ()),
bits_from_bytes (bytes.get_size ()));
}
bool
maybe_bytes_from_bits (concrete_bit_range bits,
concrete_byte_range *out);
bool
concrete_bit_range_from_mask (unsigned HOST_WIDE_INT mask,
concrete_bit_range *out);
void
get_smallest_enclosing_byte_range (const concrete_bit_range &in_bit_range,
concrete_byte_range *out_byte_range,
concrete_bit_offset *out_bit_offset);
} // namespace ana
#endif /* GCC_ANALYZER_CONCRETE_RANGES_H */