class oob_region_creation_event_capacity : public region_creation_event_capacity
{
public:
- oob_region_creation_event_capacity (tree capacity,
+ oob_region_creation_event_capacity (tree byte_capacity,
const event_loc_info &loc_info,
out_of_bounds &oob)
- : region_creation_event_capacity (capacity,
- loc_info),
- m_oob (oob)
+ : region_creation_event_capacity (byte_capacity,
+ loc_info),
+ m_oob (oob)
{
}
void prepare_for_emission (checker_path *path,
emission_id);
m_oob.m_region_creation_event_id = emission_id;
}
- private:
+ private:
out_of_bounds &m_oob;
};
}
void add_region_creation_events (const region *,
- tree capacity,
+ tree byte_capacity,
const event_loc_info &loc_info,
checker_path &emission_path) override
{
/* The memory space is described in the diagnostic message itself,
so we don't need an event for that. */
- if (capacity)
+ if (byte_capacity)
emission_path.add_event
- (make_unique<oob_region_creation_event_capacity> (capacity, loc_info,
+ (make_unique<oob_region_creation_event_capacity> (byte_capacity,
+ loc_info,
*this));
}
public:
concrete_out_of_bounds (const region_model &model,
const region *reg, tree diag_arg,
- byte_range out_of_bounds_range,
+ bit_range out_of_bounds_bits,
const svalue *sval_hint)
: out_of_bounds (model, reg, diag_arg, sval_hint),
- m_out_of_bounds_range (out_of_bounds_range)
+ m_out_of_bounds_bits (out_of_bounds_bits)
{}
bool subclass_equal_p (const pending_diagnostic &base_other) const override
const concrete_out_of_bounds &other
(static_cast <const concrete_out_of_bounds &>(base_other));
return (out_of_bounds::subclass_equal_p (other)
- && m_out_of_bounds_range == other.m_out_of_bounds_range);
+ && m_out_of_bounds_bits == other.m_out_of_bounds_bits);
+ }
+
+ bool get_out_of_bounds_bytes (byte_range *out) const
+ {
+ return m_out_of_bounds_bits.as_byte_range (out);
}
protected:
- byte_range m_out_of_bounds_range;
+ bit_range m_out_of_bounds_bits;
};
/* Abstract subclass to complaing about concrete out-of-bounds
{
public:
concrete_past_the_end (const region_model &model,
- const region *reg, tree diag_arg, byte_range range,
- tree byte_bound,
+ const region *reg, tree diag_arg, bit_range range,
+ tree bit_bound,
const svalue *sval_hint)
: concrete_out_of_bounds (model, reg, diag_arg, range, sval_hint),
- m_byte_bound (byte_bound)
- {}
+ m_bit_bound (bit_bound),
+ m_byte_bound (NULL_TREE)
+ {
+ if (m_bit_bound && TREE_CODE (m_bit_bound) == INTEGER_CST)
+ m_byte_bound
+ = wide_int_to_tree (size_type_node,
+ wi::to_offset (m_bit_bound) >> LOG2_BITS_PER_UNIT);
+ }
bool
subclass_equal_p (const pending_diagnostic &base_other) const final override
const concrete_past_the_end &other
(static_cast <const concrete_past_the_end &>(base_other));
return (concrete_out_of_bounds::subclass_equal_p (other)
- && pending_diagnostic::same_tree_p (m_byte_bound,
- other.m_byte_bound));
+ && pending_diagnostic::same_tree_p (m_bit_bound,
+ other.m_bit_bound));
}
void add_region_creation_events (const region *,
}
protected:
+ tree m_bit_bound;
tree m_byte_bound;
};
public:
concrete_buffer_overflow (const region_model &model,
const region *reg, tree diag_arg,
- byte_range range, tree byte_bound,
+ bit_range range, tree bit_bound,
const svalue *sval_hint)
- : concrete_past_the_end (model, reg, diag_arg, range, byte_bound, sval_hint)
+ : concrete_past_the_end (model, reg, diag_arg, range, bit_bound, sval_hint)
{}
const char *get_kind () const final override
if (warned)
{
- if (wi::fits_uhwi_p (m_out_of_bounds_range.m_size_in_bytes))
+ if (wi::fits_uhwi_p (m_out_of_bounds_bits.m_size_in_bits))
{
- unsigned HOST_WIDE_INT num_bad_bytes
- = m_out_of_bounds_range.m_size_in_bytes.to_uhwi ();
- if (m_diag_arg)
- inform_n (ctxt.get_location (),
- num_bad_bytes,
- "write of %wu byte to beyond the end of %qE",
- "write of %wu bytes to beyond the end of %qE",
- num_bad_bytes,
- m_diag_arg);
+ unsigned HOST_WIDE_INT num_bad_bits
+ = m_out_of_bounds_bits.m_size_in_bits.to_uhwi ();
+ if (num_bad_bits % BITS_PER_UNIT == 0)
+ {
+ unsigned HOST_WIDE_INT num_bad_bytes
+ = num_bad_bits / BITS_PER_UNIT;
+ if (m_diag_arg)
+ inform_n (ctxt.get_location (),
+ num_bad_bytes,
+ "write of %wu byte to beyond the end of %qE",
+ "write of %wu bytes to beyond the end of %qE",
+ num_bad_bytes,
+ m_diag_arg);
+ else
+ inform_n (ctxt.get_location (),
+ num_bad_bytes,
+ "write of %wu byte to beyond the end of the region",
+ "write of %wu bytes to beyond the end of the region",
+ num_bad_bytes);
+ }
else
- inform_n (ctxt.get_location (),
- num_bad_bytes,
- "write of %wu byte to beyond the end of the region",
- "write of %wu bytes to beyond the end of the region",
- num_bad_bytes);
+ {
+ if (m_diag_arg)
+ inform_n (ctxt.get_location (),
+ num_bad_bits,
+ "write of %wu bit to beyond the end of %qE",
+ "write of %wu bits to beyond the end of %qE",
+ num_bad_bits,
+ m_diag_arg);
+ else
+ inform_n (ctxt.get_location (),
+ num_bad_bits,
+ "write of %wu bit to beyond the end of the region",
+ "write of %wu bits to beyond the end of the region",
+ num_bad_bits);
+ }
}
else if (m_diag_arg)
inform (ctxt.get_location (),
}
label_text describe_final_event (const evdesc::final_event &ev)
- final override
+ final override
{
- byte_size_t start = m_out_of_bounds_range.get_start_byte_offset ();
- byte_size_t end = m_out_of_bounds_range.get_last_byte_offset ();
+ if (m_byte_bound || !m_bit_bound)
+ {
+ byte_range out_of_bounds_bytes (0, 0);
+ if (get_out_of_bounds_bytes (&out_of_bounds_bytes))
+ return describe_final_event_as_bytes (ev, out_of_bounds_bytes);
+ }
+ return describe_final_event_as_bits (ev);
+ }
+
+ label_text
+ describe_final_event_as_bytes (const evdesc::final_event &ev,
+ const byte_range &out_of_bounds_bytes)
+ {
+ byte_size_t start = out_of_bounds_bytes.get_start_byte_offset ();
+ byte_size_t end = out_of_bounds_bytes.get_last_byte_offset ();
char start_buf[WIDE_INT_PRINT_BUFFER_SIZE];
print_dec (start, start_buf, SIGNED);
char end_buf[WIDE_INT_PRINT_BUFFER_SIZE];
if (m_diag_arg)
return ev.formatted_print ("out-of-bounds write at byte %s but %qE"
" ends at byte %E", start_buf, m_diag_arg,
- m_byte_bound);
+ m_byte_bound);
return ev.formatted_print ("out-of-bounds write at byte %s but region"
" ends at byte %E", start_buf,
- m_byte_bound);
+ m_byte_bound);
}
else
{
}
}
+ label_text describe_final_event_as_bits (const evdesc::final_event &ev)
+ {
+ bit_size_t start = m_out_of_bounds_bits.get_start_bit_offset ();
+ bit_size_t end = m_out_of_bounds_bits.get_last_bit_offset ();
+ char start_buf[WIDE_INT_PRINT_BUFFER_SIZE];
+ print_dec (start, start_buf, SIGNED);
+ char end_buf[WIDE_INT_PRINT_BUFFER_SIZE];
+ print_dec (end, end_buf, SIGNED);
+
+ if (start == end)
+ {
+ if (m_diag_arg)
+ return ev.formatted_print ("out-of-bounds write at bit %s but %qE"
+ " ends at bit %E", start_buf, m_diag_arg,
+ m_bit_bound);
+ return ev.formatted_print ("out-of-bounds write at bit %s but region"
+ " ends at bit %E", start_buf,
+ m_bit_bound);
+ }
+ else
+ {
+ if (m_diag_arg)
+ return ev.formatted_print ("out-of-bounds write from bit %s till"
+ " bit %s but %qE ends at bit %E",
+ start_buf, end_buf, m_diag_arg,
+ m_bit_bound);
+ return ev.formatted_print ("out-of-bounds write from bit %s till"
+ " bit %s but region ends at bit %E",
+ start_buf, end_buf, m_bit_bound);
+ }
+ }
+
enum access_direction get_dir () const final override { return DIR_WRITE; }
};
public:
concrete_buffer_over_read (const region_model &model,
const region *reg, tree diag_arg,
- byte_range range, tree byte_bound)
- : concrete_past_the_end (model, reg, diag_arg, range, byte_bound, NULL)
+ bit_range range, tree bit_bound)
+ : concrete_past_the_end (model, reg, diag_arg, range, bit_bound, NULL)
{}
const char *get_kind () const final override
if (warned)
{
- if (wi::fits_uhwi_p (m_out_of_bounds_range.m_size_in_bytes))
+ if (wi::fits_uhwi_p (m_out_of_bounds_bits.m_size_in_bits))
{
- unsigned HOST_WIDE_INT num_bad_bytes
- = m_out_of_bounds_range.m_size_in_bytes.to_uhwi ();
- if (m_diag_arg)
- inform_n (ctxt.get_location (),
- num_bad_bytes,
- "read of %wu byte from after the end of %qE",
- "read of %wu bytes from after the end of %qE",
- num_bad_bytes,
- m_diag_arg);
+ unsigned HOST_WIDE_INT num_bad_bits
+ = m_out_of_bounds_bits.m_size_in_bits.to_uhwi ();
+ if (num_bad_bits % BITS_PER_UNIT == 0)
+ {
+ unsigned HOST_WIDE_INT num_bad_bytes
+ = num_bad_bits / BITS_PER_UNIT;
+ if (m_diag_arg)
+ inform_n (ctxt.get_location (),
+ num_bad_bytes,
+ "read of %wu byte from after the end of %qE",
+ "read of %wu bytes from after the end of %qE",
+ num_bad_bytes,
+ m_diag_arg);
+ else
+ inform_n (ctxt.get_location (),
+ num_bad_bytes,
+ "read of %wu byte from after the end of the region",
+ "read of %wu bytes from after the end of the region",
+ num_bad_bytes);
+ }
else
- inform_n (ctxt.get_location (),
- num_bad_bytes,
- "read of %wu byte from after the end of the region",
- "read of %wu bytes from after the end of the region",
- num_bad_bytes);
+ {
+ if (m_diag_arg)
+ inform_n (ctxt.get_location (),
+ num_bad_bits,
+ "read of %wu bit from after the end of %qE",
+ "read of %wu bits from after the end of %qE",
+ num_bad_bits,
+ m_diag_arg);
+ else
+ inform_n (ctxt.get_location (),
+ num_bad_bits,
+ "read of %wu bit from after the end of the region",
+ "read of %wu bits from after the end of the region",
+ num_bad_bits);
+ }
}
else if (m_diag_arg)
inform (ctxt.get_location (),
}
label_text describe_final_event (const evdesc::final_event &ev)
- final override
+ final override
{
- byte_size_t start = m_out_of_bounds_range.get_start_byte_offset ();
- byte_size_t end = m_out_of_bounds_range.get_last_byte_offset ();
+ if (m_byte_bound || !m_bit_bound)
+ {
+ byte_range out_of_bounds_bytes (0, 0);
+ if (get_out_of_bounds_bytes (&out_of_bounds_bytes))
+ return describe_final_event_as_bytes (ev, out_of_bounds_bytes);
+ }
+ return describe_final_event_as_bits (ev);
+ }
+
+ label_text
+ describe_final_event_as_bytes (const evdesc::final_event &ev,
+ const byte_range &out_of_bounds_bytes)
+ {
+ byte_size_t start = out_of_bounds_bytes.get_start_byte_offset ();
+ byte_size_t end = out_of_bounds_bytes.get_last_byte_offset ();
char start_buf[WIDE_INT_PRINT_BUFFER_SIZE];
print_dec (start, start_buf, SIGNED);
char end_buf[WIDE_INT_PRINT_BUFFER_SIZE];
}
}
+ label_text describe_final_event_as_bits (const evdesc::final_event &ev)
+ {
+ bit_size_t start = m_out_of_bounds_bits.get_start_bit_offset ();
+ bit_size_t end = m_out_of_bounds_bits.get_last_bit_offset ();
+ char start_buf[WIDE_INT_PRINT_BUFFER_SIZE];
+ print_dec (start, start_buf, SIGNED);
+ char end_buf[WIDE_INT_PRINT_BUFFER_SIZE];
+ print_dec (end, end_buf, SIGNED);
+
+ if (start == end)
+ {
+ if (m_diag_arg)
+ return ev.formatted_print ("out-of-bounds read at bit %s but %qE"
+ " ends at bit %E", start_buf, m_diag_arg,
+ m_bit_bound);
+ return ev.formatted_print ("out-of-bounds read at bit %s but region"
+ " ends at bit %E", start_buf,
+ m_bit_bound);
+ }
+ else
+ {
+ if (m_diag_arg)
+ return ev.formatted_print ("out-of-bounds read from bit %s till"
+ " bit %s but %qE ends at bit %E",
+ start_buf, end_buf, m_diag_arg,
+ m_bit_bound);
+ return ev.formatted_print ("out-of-bounds read from bit %s till"
+ " bit %s but region ends at bit %E",
+ start_buf, end_buf, m_bit_bound);
+ }
+ }
+
enum access_direction get_dir () const final override { return DIR_READ; }
};
public:
concrete_buffer_underwrite (const region_model &model,
const region *reg, tree diag_arg,
- byte_range range,
+ bit_range range,
const svalue *sval_hint)
: concrete_out_of_bounds (model, reg, diag_arg, range, sval_hint)
{}
}
label_text describe_final_event (const evdesc::final_event &ev)
- final override
+ final override
{
- byte_size_t start = m_out_of_bounds_range.get_start_byte_offset ();
- byte_size_t end = m_out_of_bounds_range.get_last_byte_offset ();
+ byte_range out_of_bounds_bytes (0, 0);
+ if (get_out_of_bounds_bytes (&out_of_bounds_bytes))
+ return describe_final_event_as_bytes (ev, out_of_bounds_bytes);
+ return describe_final_event_as_bits (ev);
+ }
+
+ label_text
+ describe_final_event_as_bytes (const evdesc::final_event &ev,
+ const byte_range &out_of_bounds_bytes)
+ {
+ byte_size_t start = out_of_bounds_bytes.get_start_byte_offset ();
+ byte_size_t end = out_of_bounds_bytes.get_last_byte_offset ();
char start_buf[WIDE_INT_PRINT_BUFFER_SIZE];
print_dec (start, start_buf, SIGNED);
char end_buf[WIDE_INT_PRINT_BUFFER_SIZE];
{
if (m_diag_arg)
return ev.formatted_print ("out-of-bounds write at byte %s but %qE"
- " starts at byte 0", start_buf,
- m_diag_arg);
+ " starts at byte 0",
+ start_buf, m_diag_arg);
return ev.formatted_print ("out-of-bounds write at byte %s but region"
" starts at byte 0", start_buf);
}
}
}
+ label_text
+ describe_final_event_as_bits (const evdesc::final_event &ev)
+ {
+ bit_size_t start = m_out_of_bounds_bits.get_start_bit_offset ();
+ bit_size_t end = m_out_of_bounds_bits.get_last_bit_offset ();
+ char start_buf[WIDE_INT_PRINT_BUFFER_SIZE];
+ print_dec (start, start_buf, SIGNED);
+ char end_buf[WIDE_INT_PRINT_BUFFER_SIZE];
+ print_dec (end, end_buf, SIGNED);
+
+ if (start == end)
+ {
+ if (m_diag_arg)
+ return ev.formatted_print ("out-of-bounds write at bit %s but %qE"
+ " starts at bit 0",
+ start_buf, m_diag_arg);
+ return ev.formatted_print ("out-of-bounds write at bit %s but region"
+ " starts at bit 0", start_buf);
+ }
+ else
+ {
+ if (m_diag_arg)
+ return ev.formatted_print ("out-of-bounds write from bit %s till"
+ " bit %s but %qE starts at bit 0",
+ start_buf, end_buf, m_diag_arg);
+ return ev.formatted_print ("out-of-bounds write from bit %s till"
+ " bit %s but region starts at bit 0",
+ start_buf, end_buf);;
+ }
+ }
+
enum access_direction get_dir () const final override { return DIR_WRITE; }
};
public:
concrete_buffer_under_read (const region_model &model,
const region *reg, tree diag_arg,
- byte_range range)
+ bit_range range)
: concrete_out_of_bounds (model, reg, diag_arg, range, NULL)
{}
}
label_text describe_final_event (const evdesc::final_event &ev)
- final override
+ final override
{
- byte_size_t start = m_out_of_bounds_range.get_start_byte_offset ();
- byte_size_t end = m_out_of_bounds_range.get_last_byte_offset ();
+ byte_range out_of_bounds_bytes (0, 0);
+ if (get_out_of_bounds_bytes (&out_of_bounds_bytes))
+ return describe_final_event_as_bytes (ev, out_of_bounds_bytes);
+ return describe_final_event_as_bits (ev);
+ }
+
+ label_text
+ describe_final_event_as_bytes (const evdesc::final_event &ev,
+ const byte_range &out_of_bounds_bytes)
+ {
+ byte_size_t start = out_of_bounds_bytes.get_start_byte_offset ();
+ byte_size_t end = out_of_bounds_bytes.get_last_byte_offset ();
char start_buf[WIDE_INT_PRINT_BUFFER_SIZE];
print_dec (start, start_buf, SIGNED);
char end_buf[WIDE_INT_PRINT_BUFFER_SIZE];
}
}
+ label_text describe_final_event_as_bits (const evdesc::final_event &ev)
+ {
+ bit_size_t start = m_out_of_bounds_bits.get_start_bit_offset ();
+ bit_size_t end = m_out_of_bounds_bits.get_last_bit_offset ();
+ char start_buf[WIDE_INT_PRINT_BUFFER_SIZE];
+ print_dec (start, start_buf, SIGNED);
+ char end_buf[WIDE_INT_PRINT_BUFFER_SIZE];
+ print_dec (end, end_buf, SIGNED);
+
+ if (start == end)
+ {
+ if (m_diag_arg)
+ return ev.formatted_print ("out-of-bounds read at bit %s but %qE"
+ " starts at bit 0", start_buf,
+ m_diag_arg);
+ return ev.formatted_print ("out-of-bounds read at bit %s but region"
+ " starts at bit 0", start_buf);
+ }
+ else
+ {
+ if (m_diag_arg)
+ return ev.formatted_print ("out-of-bounds read from bit %s till"
+ " bit %s but %qE starts at bit 0",
+ start_buf, end_buf, m_diag_arg);
+ return ev.formatted_print ("out-of-bounds read from bit %s till"
+ " bit %s but region starts at bit 0",
+ start_buf, end_buf);;
+ }
+ }
+
enum access_direction get_dir () const final override { return DIR_READ; }
};
region_offset reg_offset = reg->get_offset (m_mgr);
const region *base_reg = reg_offset.get_base_region ();
- /* Find out how many bytes were accessed. */
- const svalue *num_bytes_sval = reg->get_byte_size_sval (m_mgr);
- tree num_bytes_tree = maybe_get_integer_cst_tree (num_bytes_sval);
- /* Bail out if 0 bytes are accessed. */
- if (num_bytes_tree && zerop (num_bytes_tree))
+ /* Find out how many bits were accessed. */
+ const svalue *num_bits_sval = reg->get_bit_size_sval (m_mgr);
+ tree num_bits_tree = maybe_get_integer_cst_tree (num_bits_sval);
+ /* Bail out if 0 bits are accessed. */
+ if (num_bits_tree && zerop (num_bits_tree))
return true;
- /* Get the capacity of the buffer. */
- const svalue *capacity = get_capacity (base_reg);
- tree cst_capacity_tree = maybe_get_integer_cst_tree (capacity);
+ /* Get the capacity of the buffer (in bytes). */
+ const svalue *byte_capacity = get_capacity (base_reg);
+ tree cst_byte_capacity_tree = maybe_get_integer_cst_tree (byte_capacity);
/* The constant offset from a pointer is represented internally as a sizetype
but should be interpreted as a signed value here. The statement below
For example, this is needed for out-of-bounds-3.c test1 to pass when
compiled with a 64-bit gcc build targeting 32-bit systems. */
- byte_offset_t offset;
+ bit_offset_t bit_offset;
if (!reg_offset.symbolic_p ())
- offset = wi::sext (reg_offset.get_bit_offset () >> LOG2_BITS_PER_UNIT,
- TYPE_PRECISION (size_type_node));
+ bit_offset = wi::sext (reg_offset.get_bit_offset (),
+ TYPE_PRECISION (size_type_node));
/* If any of the base region, the offset, or the number of bytes accessed
are symbolic, we have to reason about symbolic values. */
- if (base_reg->symbolic_p () || reg_offset.symbolic_p () || !num_bytes_tree)
+ if (base_reg->symbolic_p () || reg_offset.symbolic_p () || !num_bits_tree)
{
const svalue* byte_offset_sval;
if (!reg_offset.symbolic_p ())
{
- tree offset_tree = wide_int_to_tree (integer_type_node, offset);
+ tree byte_offset_tree
+ = wide_int_to_tree (integer_type_node,
+ bit_offset >> LOG2_BITS_PER_UNIT);
byte_offset_sval
- = m_mgr->get_or_create_constant_svalue (offset_tree);
+ = m_mgr->get_or_create_constant_svalue (byte_offset_tree);
}
else
byte_offset_sval = reg_offset.get_symbolic_byte_offset ();
+ const svalue *num_bytes_sval = reg->get_byte_size_sval (m_mgr);
return check_symbolic_bounds (base_reg, byte_offset_sval, num_bytes_sval,
- capacity, dir, sval_hint, ctxt);
+ byte_capacity, dir, sval_hint, ctxt);
}
/* Otherwise continue to check with concrete values. */
- byte_range out (0, 0);
+ bit_range bits_outside (0, 0);
bool oob_safe = true;
- /* NUM_BYTES_TREE should always be interpreted as unsigned. */
- byte_offset_t num_bytes_unsigned = wi::to_offset (num_bytes_tree);
- byte_range read_bytes (offset, num_bytes_unsigned);
- /* If read_bytes has a subset < 0, we do have an underwrite. */
- if (read_bytes.falls_short_of_p (0, &out))
+ /* NUM_BITS_TREE should always be interpreted as unsigned. */
+ bit_offset_t num_bits_unsigned = wi::to_offset (num_bits_tree);
+ bit_range read_bits (bit_offset, num_bits_unsigned);
+ /* If read_bits has a subset < 0, we do have an underwrite. */
+ if (read_bits.falls_short_of_p (0, &bits_outside))
{
tree diag_arg = get_representative_tree (base_reg);
switch (dir)
gcc_assert (sval_hint == nullptr);
ctxt->warn (make_unique<concrete_buffer_under_read> (*this, reg,
diag_arg,
- out));
+ bits_outside));
oob_safe = false;
break;
case DIR_WRITE:
ctxt->warn (make_unique<concrete_buffer_underwrite> (*this,
reg, diag_arg,
- out,
+ bits_outside,
sval_hint));
oob_safe = false;
break;
/* For accesses past the end, we do need a concrete capacity. No need to
do a symbolic check here because the inequality check does not reason
whether constants are greater than symbolic values. */
- if (!cst_capacity_tree)
- return oob_safe;
+ if (!cst_byte_capacity_tree)
+ return oob_safe;
- byte_range buffer (0, wi::to_offset (cst_capacity_tree));
- /* If READ_BYTES exceeds BUFFER, we do have an overflow. */
- if (read_bytes.exceeds_p (buffer, &out))
+ bit_range buffer (0, wi::to_offset (cst_byte_capacity_tree) * BITS_PER_UNIT);
+ /* If READ_BITS exceeds BUFFER, we do have an overflow. */
+ if (read_bits.exceeds_p (buffer, &bits_outside))
{
- tree byte_bound = wide_int_to_tree (size_type_node,
- buffer.get_next_byte_offset ());
+ tree bit_bound = wide_int_to_tree (size_type_node,
+ buffer.get_next_bit_offset ());
tree diag_arg = get_representative_tree (base_reg);
switch (dir)
gcc_assert (sval_hint == nullptr);
ctxt->warn (make_unique<concrete_buffer_over_read> (*this,
reg, diag_arg,
- out, byte_bound));
+ bits_outside,
+ bit_bound));
oob_safe = false;
break;
case DIR_WRITE:
ctxt->warn (make_unique<concrete_buffer_overflow> (*this,
reg, diag_arg,
- out, byte_bound,
+ bits_outside,
+ bit_bound,
sval_hint));
oob_safe = false;
break;