/* 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))
+ return;
/* Get the capacity of the buffer. */
const svalue *capacity = get_capacity (base_reg);
void
byte_range::dump_to_pp (pretty_printer *pp) const
{
- if (m_size_in_bytes == 1)
+ if (m_size_in_bytes == 0)
+ {
+ pp_string (pp, "empty");
+ }
+ else if (m_size_in_bytes == 1)
{
pp_string (pp, "byte ");
pp_wide_int (pp, m_start_byte_offset, SIGNED);
byte_range::exceeds_p (const byte_range &other,
byte_range *out_overhanging_byte_range) const
{
- if (other.get_last_byte_offset () < get_last_byte_offset ())
+ gcc_assert (!empty_p ());
+
+ if (other.get_next_byte_offset () < get_next_byte_offset ())
{
/* THIS definitely exceeds OTHER. */
byte_offset_t start = MAX (get_start_byte_offset (),
byte_range::falls_short_of_p (byte_offset_t offset,
byte_range *out_fall_short_bytes) const
{
+ gcc_assert (!empty_p ());
+
if (get_start_byte_offset () < offset)
{
/* THIS falls short of OFFSET. */
void dump_to_pp (pretty_printer *pp) const;
void dump () const;
+ bool empty_p () const
+ {
+ return m_size_in_bits == 0;
+ }
+
bit_offset_t get_start_bit_offset () const
{
return m_start_bit_offset;
}
bit_offset_t get_last_bit_offset () const
{
+ gcc_assert (!empty_p ());
return get_next_bit_offset () - 1;
}
void dump_to_pp (pretty_printer *pp) const;
void dump () const;
+ bool empty_p () const
+ {
+ return m_size_in_bytes == 0;
+ }
+
bool contains_p (byte_offset_t offset) const
{
return (offset >= get_start_byte_offset ()
}
byte_offset_t get_last_byte_offset () const
{
+ gcc_assert (!empty_p ());
return m_start_byte_offset + m_size_in_bytes - 1;
}
--- /dev/null
+/* { dg-additional-options "-Wno-stringop-overflow"} */
+/* -Wstringop-overflow= triggers on test5. */
+
+#include <stdint.h>
+#include <stdlib.h>
+
+void test1 (void)
+{
+ int32_t buf[1];
+ /* Zero bytes written on non-zero allocation. */
+ __builtin_memset (buf, 0, 0);
+}
+
+void test2 (void)
+{
+ /* ISO C forbids zero-size arrays but GCC compiles this to an
+ zero-sized array without -Wpedantic. */
+ int32_t buf[0];
+ /* Write on zero capacity. */
+ __builtin_memset (buf, 0, sizeof (int32_t)); /* { dg-line test2 } */
+
+ /* { dg-warning "overflow" "warning" { target *-*-* } test2 } */
+ /* { dg-message "from byte 0 till byte 3" "final event" { target *-*-* } test2 } */
+}
+
+void test3 (void)
+{
+ int32_t buf[0];
+ /* Zero bytes written on zero capacity. */
+ __builtin_memset (buf, 0, 0);
+}
+
+void test4 (void)
+{
+ int32_t *buf = malloc (sizeof (int32_t));
+ if (!buf)
+ return;
+
+ /* Zero bytes written on non-zero allocation. */
+ __builtin_memset (buf, 0, 0);
+ free (buf);
+}
+
+void test5 (void)
+{
+ int32_t *buf = malloc (0);
+ if (!buf)
+ return;
+
+ /* Write on zero capacity. */
+ __builtin_memset (buf, 0, sizeof (int32_t)); /* { dg-line test5 } */
+ free (buf);
+
+ /* { dg-warning "overflow" "warning" { target *-*-* } test5 } */
+ /* { dg-message "from byte 0 till byte 3" "final event" { target *-*-* } test5 } */
+}
+
+void test6 (void)
+{
+ int32_t *buf = malloc (0);
+ if (!buf)
+ return;
+
+ /* Zero bytes written on zero capacity. */
+ __builtin_memset (buf, 0, 0);
+ free (buf);
+}
--- /dev/null
+int buf_size;
+
+int
+main (void)
+{
+ char buf[buf_size];
+
+ __builtin_memset (&buf[1], 0, buf_size);
+
+ return 0;
+}