Clear entire "location" in value constructor
[deliverable/binutils-gdb.git] / gdb / value.c
index fcd0007c1eb2681c78aea8556f33e35f5d139685..6bb6b8eb61ebfe5509d9a423643d124772a1fb14 100644 (file)
@@ -41,6 +41,8 @@
 #include "user-regs.h"
 #include <algorithm>
 #include "completer.h"
+#include "selftest.h"
+#include "common/array-view.h"
 
 /* Definition of a user function.  */
 struct internal_function
@@ -66,11 +68,23 @@ struct range
 
   /* Length of the range.  */
   LONGEST length;
-};
 
-typedef struct range range_s;
+  /* Returns true if THIS is strictly less than OTHER, useful for
+     searching.  We keep ranges sorted by offset and coalesce
+     overlapping and contiguous ranges, so this just compares the
+     starting offset.  */
 
-DEF_VEC_O(range_s);
+  bool operator< (const range &other) const
+  {
+    return offset < other.offset;
+  }
+
+  /* Returns true if THIS is equal to OTHER.  */
+  bool operator== (const range &other) const
+  {
+    return offset == other.offset && length == other.length;
+  }
+};
 
 /* Returns true if the ranges defined by [offset1, offset1+len1) and
    [offset2, offset2+len2) overlap.  */
@@ -86,25 +100,14 @@ ranges_overlap (LONGEST offset1, LONGEST len1,
   return (l < h);
 }
 
-/* Returns true if the first argument is strictly less than the
-   second, useful for VEC_lower_bound.  We keep ranges sorted by
-   offset and coalesce overlapping and contiguous ranges, so this just
-   compares the starting offset.  */
-
-static int
-range_lessthan (const range_s *r1, const range_s *r2)
-{
-  return r1->offset < r2->offset;
-}
-
 /* Returns true if RANGES contains any range that overlaps [OFFSET,
    OFFSET+LENGTH).  */
 
 static int
-ranges_contain (VEC(range_s) *ranges, LONGEST offset, LONGEST length)
+ranges_contain (const std::vector<range> &ranges, LONGEST offset,
+               LONGEST length)
 {
-  range_s what;
-  LONGEST i;
+  range what;
 
   what.offset = offset;
   what.length = length;
@@ -140,21 +143,22 @@ ranges_contain (VEC(range_s) *ranges, LONGEST offset, LONGEST length)
        I=1
   */
 
-  i = VEC_lower_bound (range_s, ranges, &what, range_lessthan);
 
-  if (i > 0)
+  auto i = std::lower_bound (ranges.begin (), ranges.end (), what);
+
+  if (i > ranges.begin ())
     {
-      struct range *bef = VEC_index (range_s, ranges, i - 1);
+      const struct range &bef = *(i - 1);
 
-      if (ranges_overlap (bef->offset, bef->length, offset, length))
+      if (ranges_overlap (bef.offset, bef.length, offset, length))
        return 1;
     }
 
-  if (i < VEC_length (range_s, ranges))
+  if (i < ranges.end ())
     {
-      struct range *r = VEC_index (range_s, ranges, i);
+      const struct range &r = *i;
 
-      if (ranges_overlap (r->offset, r->length, offset, length))
+      if (ranges_overlap (r.offset, r.length, offset, length))
        return 1;
     }
 
@@ -176,16 +180,10 @@ struct value
       type (type_),
       enclosing_type (type_)
   {
-    location.address = 0;
   }
 
   ~value ()
   {
-    /* If there's an associated parent value, drop our reference to
-       it.  */
-    if (parent != NULL)
-      value_decref (parent);
-
     if (VALUE_LVAL (this) == lval_computed)
       {
        const struct lval_funcs *funcs = location.computed.funcs;
@@ -195,10 +193,6 @@ struct value
       }
     else if (VALUE_LVAL (this) == lval_xcallable)
       delete location.xm_worker;
-
-    xfree (contents);
-    VEC_free (range_s, unavailable);
-    VEC_free (range_s, optimized_out);
   }
 
   DISABLE_COPY_AND_ASSIGN (value);
@@ -267,7 +261,7 @@ struct value
       /* Closure for those functions to use.  */
       void *closure;
     } computed;
-  } location;
+  } location {};
 
   /* Describes offset of a value within lval of a structure in target
      addressable memory units.  Note also the member embedded_offset
@@ -292,7 +286,7 @@ struct value
   /* Only used for bitfields; the containing value.  This allows a
      single read from the target when displaying multiple
      bitfields.  */
-  struct value *parent = nullptr;
+  value_ref_ptr parent;
 
   /* Type of the value.  */
   struct type *type;
@@ -343,7 +337,7 @@ struct value
 
   /* Actual contents of the value.  Target byte-order.  NULL or not
      valid if lazy is nonzero.  */
-  gdb_byte *contents = nullptr;
+  gdb::unique_xmalloc_ptr<gdb_byte> contents;
 
   /* Unavailable ranges in CONTENTS.  We mark unavailable ranges,
      rather than available, since the common and default case is for a
@@ -351,7 +345,7 @@ struct value
      The unavailable ranges are tracked in bits.  Note that a contents
      bit that has been optimized out doesn't really exist in the
      program, so it can't be marked unavailable either.  */
-  VEC(range_s) *unavailable = nullptr;
+  std::vector<range> unavailable;
 
   /* Likewise, but for optimized out contents (a chunk of the value of
      a variable that does not actually exist in the program).  If LVAL
@@ -360,7 +354,7 @@ struct value
      saved registers and optimized-out program variables values are
      treated pretty much the same, except not-saved registers have a
      different string representation and related error strings.  */
-  VEC(range_s) *optimized_out = nullptr;
+  std::vector<range> optimized_out;
 };
 
 /* See value.h.  */
@@ -404,7 +398,7 @@ value_entirely_available (struct value *value)
   if (value->lazy)
     value_fetch_lazy (value);
 
-  if (VEC_empty (range_s, value->unavailable))
+  if (value->unavailable.empty ())
     return 1;
   return 0;
 }
@@ -415,20 +409,20 @@ value_entirely_available (struct value *value)
 
 static int
 value_entirely_covered_by_range_vector (struct value *value,
-                                       VEC(range_s) **ranges)
+                                       const std::vector<range> &ranges)
 {
   /* We can only tell whether the whole value is optimized out /
      unavailable when we try to read it.  */
   if (value->lazy)
     value_fetch_lazy (value);
 
-  if (VEC_length (range_s, *ranges) == 1)
+  if (ranges.size () == 1)
     {
-      struct range *t = VEC_index (range_s, *ranges, 0);
+      const struct range &t = ranges[0];
 
-      if (t->offset == 0
-         && t->length == (TARGET_CHAR_BIT
-                          * TYPE_LENGTH (value_enclosing_type (value))))
+      if (t.offset == 0
+         && t.length == (TARGET_CHAR_BIT
+                         * TYPE_LENGTH (value_enclosing_type (value))))
        return 1;
     }
 
@@ -438,24 +432,23 @@ value_entirely_covered_by_range_vector (struct value *value,
 int
 value_entirely_unavailable (struct value *value)
 {
-  return value_entirely_covered_by_range_vector (value, &value->unavailable);
+  return value_entirely_covered_by_range_vector (value, value->unavailable);
 }
 
 int
 value_entirely_optimized_out (struct value *value)
 {
-  return value_entirely_covered_by_range_vector (value, &value->optimized_out);
+  return value_entirely_covered_by_range_vector (value, value->optimized_out);
 }
 
 /* Insert into the vector pointed to by VECTORP the bit range starting of
    OFFSET bits, and extending for the next LENGTH bits.  */
 
 static void
-insert_into_bit_range_vector (VEC(range_s) **vectorp,
+insert_into_bit_range_vector (std::vector<range> *vectorp,
                              LONGEST offset, LONGEST length)
 {
-  range_s newr;
-  int i;
+  range newr;
 
   /* Insert the range sorted.  If there's overlap or the new range
      would be contiguous with an existing range, merge.  */
@@ -543,76 +536,77 @@ insert_into_bit_range_vector (VEC(range_s) **vectorp,
 
   */
 
-  i = VEC_lower_bound (range_s, *vectorp, &newr, range_lessthan);
-  if (i > 0)
+  auto i = std::lower_bound (vectorp->begin (), vectorp->end (), newr);
+  if (i > vectorp->begin ())
     {
-      struct range *bef = VEC_index (range_s, *vectorp, i - 1);
+      struct range &bef = *(i - 1);
 
-      if (ranges_overlap (bef->offset, bef->length, offset, length))
+      if (ranges_overlap (bef.offset, bef.length, offset, length))
        {
          /* #1 */
-         ULONGEST l = std::min (bef->offset, offset);
-         ULONGEST h = std::max (bef->offset + bef->length, offset + length);
+         ULONGEST l = std::min (bef.offset, offset);
+         ULONGEST h = std::max (bef.offset + bef.length, offset + length);
 
-         bef->offset = l;
-         bef->length = h - l;
+         bef.offset = l;
+         bef.length = h - l;
          i--;
        }
-      else if (offset == bef->offset + bef->length)
+      else if (offset == bef.offset + bef.length)
        {
          /* #2 */
-         bef->length += length;
+         bef.length += length;
          i--;
        }
       else
        {
          /* #3 */
-         VEC_safe_insert (range_s, *vectorp, i, &newr);
+         i = vectorp->insert (i, newr);
        }
     }
   else
     {
       /* #4 */
-      VEC_safe_insert (range_s, *vectorp, i, &newr);
+      i = vectorp->insert (i, newr);
     }
 
   /* Check whether the ranges following the one we've just added or
      touched can be folded in (#5 above).  */
-  if (i + 1 < VEC_length (range_s, *vectorp))
+  if (i != vectorp->end () && i + 1 < vectorp->end ())
     {
-      struct range *t;
-      struct range *r;
       int removed = 0;
-      int next = i + 1;
+      auto next = i + 1;
 
       /* Get the range we just touched.  */
-      t = VEC_index (range_s, *vectorp, i);
+      struct range &t = *i;
       removed = 0;
 
       i = next;
-      for (; VEC_iterate (range_s, *vectorp, i, r); i++)
-       if (r->offset <= t->offset + t->length)
-         {
-           ULONGEST l, h;
-
-           l = std::min (t->offset, r->offset);
-           h = std::max (t->offset + t->length, r->offset + r->length);
-
-           t->offset = l;
-           t->length = h - l;
-
-           removed++;
-         }
-       else
-         {
-           /* If we couldn't merge this one, we won't be able to
-              merge following ones either, since the ranges are
-              always sorted by OFFSET.  */
-           break;
-         }
+      for (; i < vectorp->end (); i++)
+       {
+         struct range &r = *i;
+         if (r.offset <= t.offset + t.length)
+           {
+             ULONGEST l, h;
+
+             l = std::min (t.offset, r.offset);
+             h = std::max (t.offset + t.length, r.offset + r.length);
+
+             t.offset = l;
+             t.length = h - l;
+
+             removed++;
+           }
+         else
+           {
+             /* If we couldn't merge this one, we won't be able to
+                merge following ones either, since the ranges are
+                always sorted by OFFSET.  */
+             break;
+           }
+       }
 
       if (removed != 0)
-       VEC_block_remove (range_s, *vectorp, next, removed);
+       vectorp->erase (next, next + removed);
     }
 }
 
@@ -638,15 +632,17 @@ mark_value_bytes_unavailable (struct value *value,
    found, or -1 if none was found.  */
 
 static int
-find_first_range_overlap (VEC(range_s) *ranges, int pos,
+find_first_range_overlap (const std::vector<range> *ranges, int pos,
                          LONGEST offset, LONGEST length)
 {
-  range_s *r;
   int i;
 
-  for (i = pos; VEC_iterate (range_s, ranges, i, r); i++)
-    if (ranges_overlap (r->offset, r->length, offset, length))
-      return i;
+  for (i = pos; i < ranges->size (); i++)
+    {
+      const range &r = (*ranges)[i];
+      if (ranges_overlap (r.offset, r.length, offset, length))
+       return i;
+    }
 
   return -1;
 }
@@ -759,7 +755,7 @@ memcmp_with_bit_offsets (const gdb_byte *ptr1, size_t offset1_bits,
 struct ranges_and_idx
 {
   /* The ranges.  */
-  VEC(range_s) *ranges;
+  const std::vector<range> *ranges;
 
   /* The range we've last found in RANGES.  Given ranges are sorted,
      we can start the next lookup here.  */
@@ -793,12 +789,12 @@ find_first_range_overlap_and_match (struct ranges_and_idx *rp1,
     return 0;
   else
     {
-      range_s *r1, *r2;
+      const range *r1, *r2;
       ULONGEST l1, h1;
       ULONGEST l2, h2;
 
-      r1 = VEC_index (range_s, rp1->ranges, rp1->idx);
-      r2 = VEC_index (range_s, rp2->ranges, rp2->idx);
+      r1 = &(*rp1->ranges)[rp1->idx];
+      r2 = &(*rp2->ranges)[rp2->idx];
 
       /* Get the unavailable windows intersected by the incoming
         ranges.  The first and last ranges that overlap the argument
@@ -854,10 +850,10 @@ value_contents_bits_eq (const struct value *val1, int offset1,
 
   memset (&rp1, 0, sizeof (rp1));
   memset (&rp2, 0, sizeof (rp2));
-  rp1[0].ranges = val1->unavailable;
-  rp2[0].ranges = val2->unavailable;
-  rp1[1].ranges = val1->optimized_out;
-  rp2[1].ranges = val2->optimized_out;
+  rp1[0].ranges = &val1->unavailable;
+  rp2[0].ranges = &val2->unavailable;
+  rp1[1].ranges = &val1->optimized_out;
+  rp2[1].ranges = &val2->optimized_out;
 
   while (length > 0)
     {
@@ -884,8 +880,8 @@ value_contents_bits_eq (const struct value *val1, int offset1,
        }
 
       /* Compare the available/valid contents.  */
-      if (memcmp_with_bit_offsets (val1->contents, offset1,
-                                  val2->contents, offset2, l) != 0)
+      if (memcmp_with_bit_offsets (val1->contents.get (), offset1,
+                                  val2->contents.get (), offset2, l) != 0)
        return false;
 
       length -= h;
@@ -1021,8 +1017,8 @@ allocate_value_contents (struct value *val)
   if (!val->contents)
     {
       check_type_length_before_alloc (val->enclosing_type);
-      val->contents
-       = (gdb_byte *) xzalloc (TYPE_LENGTH (val->enclosing_type));
+      val->contents.reset
+       ((gdb_byte *) xzalloc (TYPE_LENGTH (val->enclosing_type)));
     }
 }
 
@@ -1128,7 +1124,7 @@ set_value_bitsize (struct value *value, LONGEST bit)
 struct value *
 value_parent (const struct value *value)
 {
-  return value->parent;
+  return value->parent.get ();
 }
 
 /* See value.h.  */
@@ -1136,12 +1132,7 @@ value_parent (const struct value *value)
 void
 set_value_parent (struct value *value, struct value *parent)
 {
-  struct value *old = value->parent;
-
-  value->parent = parent;
-  if (parent != NULL)
-    value_incref (parent);
-  value_decref (old);
+  value->parent = value_ref_ptr::new_reference (parent);
 }
 
 gdb_byte *
@@ -1151,14 +1142,14 @@ value_contents_raw (struct value *value)
   int unit_size = gdbarch_addressable_memory_unit_size (arch);
 
   allocate_value_contents (value);
-  return value->contents + value->embedded_offset * unit_size;
+  return value->contents.get () + value->embedded_offset * unit_size;
 }
 
 gdb_byte *
 value_contents_all_raw (struct value *value)
 {
   allocate_value_contents (value);
-  return value->contents;
+  return value->contents.get ();
 }
 
 struct type *
@@ -1220,7 +1211,7 @@ error_value_optimized_out (void)
 static void
 require_not_optimized_out (const struct value *value)
 {
-  if (!VEC_empty (range_s, value->optimized_out))
+  if (!value->optimized_out.empty ())
     {
       if (value->lval == lval_register)
        error (_("register has not been saved in frame"));
@@ -1232,7 +1223,7 @@ require_not_optimized_out (const struct value *value)
 static void
 require_available (const struct value *value)
 {
-  if (!VEC_empty (range_s, value->unavailable))
+  if (!value->unavailable.empty ())
     throw_error (NOT_AVAILABLE_ERROR, _("value is not available"));
 }
 
@@ -1241,14 +1232,14 @@ value_contents_for_printing (struct value *value)
 {
   if (value->lazy)
     value_fetch_lazy (value);
-  return value->contents;
+  return value->contents.get ();
 }
 
 const gdb_byte *
 value_contents_for_printing_const (const struct value *value)
 {
   gdb_assert (!value->lazy);
-  return value->contents;
+  return value->contents.get ();
 }
 
 const gdb_byte *
@@ -1264,19 +1255,16 @@ value_contents_all (struct value *value)
    SRC_BIT_OFFSET+BIT_LENGTH) ranges into *DST_RANGE, adjusted.  */
 
 static void
-ranges_copy_adjusted (VEC (range_s) **dst_range, int dst_bit_offset,
-                     VEC (range_s) *src_range, int src_bit_offset,
+ranges_copy_adjusted (std::vector<range> *dst_range, int dst_bit_offset,
+                     const std::vector<range> &src_range, int src_bit_offset,
                      int bit_length)
 {
-  range_s *r;
-  int i;
-
-  for (i = 0; VEC_iterate (range_s, src_range, i, r); i++)
+  for (const range &r : src_range)
     {
       ULONGEST h, l;
 
-      l = std::max (r->offset, (LONGEST) src_bit_offset);
-      h = std::min (r->offset + r->length,
+      l = std::max (r.offset, (LONGEST) src_bit_offset);
+      h = std::min (r.offset + r.length,
                    (LONGEST) src_bit_offset + bit_length);
 
       if (l < h)
@@ -1415,7 +1403,7 @@ value_optimized_out (struct value *value)
 {
   /* We can only know if a value is optimized out once we have tried to
      fetch it.  */
-  if (VEC_empty (range_s, value->optimized_out) && value->lazy)
+  if (value->optimized_out.empty () && value->lazy)
     {
       TRY
        {
@@ -1428,7 +1416,7 @@ value_optimized_out (struct value *value)
       END_CATCH
     }
 
-  return !VEC_empty (range_s, value->optimized_out);
+  return !value->optimized_out.empty ();
 }
 
 /* Mark contents of VALUE as optimized out, starting at OFFSET bytes, and
@@ -1521,7 +1509,7 @@ value_address (const struct value *value)
   if (value->lval != lval_memory)
     return 0;
   if (value->parent != NULL)
-    return value_address (value->parent) + value->offset;
+    return value_address (value->parent.get ()) + value->offset;
   if (NULL != TYPE_DATA_LOCATION (value_type (value)))
     {
       gdb_assert (PROP_CONST == TYPE_DATA_LOCATION_KIND (value_type (value)));
@@ -1583,14 +1571,12 @@ value_mark (void)
   return all_values.back ().get ();
 }
 
-/* Take a reference to VAL.  VAL will not be deallocated until all
-   references are released.  */
+/* See value.h.  */
 
-struct value *
+void
 value_incref (struct value *val)
 {
   val->reference_count++;
-  return val;
 }
 
 /* Release a reference to VAL, which was acquired with value_incref.
@@ -1627,8 +1613,6 @@ value_free_to_mark (const struct value *mark)
 value_ref_ptr
 release_value (struct value *val)
 {
-  struct value *v;
-
   if (val == nullptr)
     return value_ref_ptr ();
 
@@ -1646,7 +1630,7 @@ release_value (struct value *val)
   /* We must always return an owned reference.  Normally this happens
      because we transfer the reference from the value chain, but in
      this case the value was not on the chain.  */
-  return value_ref_ptr (value_incref (val));
+  return value_ref_ptr::new_reference (val);
 }
 
 /* See value.h.  */
@@ -1698,9 +1682,9 @@ value_copy (struct value *arg)
              TYPE_LENGTH (value_enclosing_type (arg)));
 
     }
-  val->unavailable = VEC_copy (range_s, arg->unavailable);
-  val->optimized_out = VEC_copy (range_s, arg->optimized_out);
-  set_value_parent (val, arg->parent);
+  val->unavailable = arg->unavailable;
+  val->optimized_out = arg->optimized_out;
+  val->parent = arg->parent;
   if (VALUE_LVAL (val) == lval_computed)
     {
       const struct lval_funcs *funcs = val->location.computed.funcs;
@@ -1802,8 +1786,6 @@ set_value_component_location (struct value *component,
 int
 record_latest_value (struct value *val)
 {
-  int i;
-
   /* We don't want this value to have anything to do with the inferior anymore.
      In particular, "set $1 = 50" should not affect the variable from which
      the value was taken, and fast watchpoints should be able to assume that
@@ -1825,7 +1807,6 @@ record_latest_value (struct value *val)
 struct value *
 access_value_history (int num)
 {
-  int i;
   int absnum = num;
 
   if (absnum <= 0)
@@ -2520,7 +2501,6 @@ preserve_values (struct objfile *objfile)
 {
   htab_t copied_types;
   struct internalvar *var;
-  int i;
 
   /* Create the hash table.  We allocate on the objfile's obstack, since
      it is soon to be deleted.  */
@@ -2894,7 +2874,8 @@ set_value_enclosing_type (struct value *val, struct type *new_encl_type)
     {
       check_type_length_before_alloc (new_encl_type);
       val->contents
-       = (gdb_byte *) xrealloc (val->contents, TYPE_LENGTH (new_encl_type));
+       .reset ((gdb_byte *) xrealloc (val->contents.release (),
+                                      TYPE_LENGTH (new_encl_type)));
     }
 
   val->enclosing_type = new_encl_type;
@@ -3081,7 +3062,7 @@ value_fn_field (struct value **arg1p, struct fn_field *f,
 
       set_value_address (v,
        gdbarch_convert_from_func_ptr_addr
-          (gdbarch, BMSYMBOL_VALUE_ADDRESS (msym), &current_target));
+          (gdbarch, BMSYMBOL_VALUE_ADDRESS (msym), target_stack));
     }
 
   if (arg1p)
@@ -3749,8 +3730,8 @@ value_fetch_lazy (struct value *val)
   /* A value is either lazy, or fully fetched.  The
      availability/validity is only established as we try to fetch a
      value.  */
-  gdb_assert (VEC_empty (range_s, val->optimized_out));
-  gdb_assert (VEC_empty (range_s, val->unavailable));
+  gdb_assert (val->optimized_out.empty ());
+  gdb_assert (val->unavailable.empty ());
   if (value_bitsize (val))
     {
       /* To read a lazy bitfield, read the entire enclosing value.  This
@@ -3921,6 +3902,148 @@ isvoid_internal_fn (struct gdbarch *gdbarch,
   return value_from_longest (builtin_type (gdbarch)->builtin_int, ret);
 }
 
+#if GDB_SELF_TEST
+namespace selftests
+{
+
+/* Test the ranges_contain function.  */
+
+static void
+test_ranges_contain ()
+{
+  std::vector<range> ranges;
+  range r;
+
+  /* [10, 14] */
+  r.offset = 10;
+  r.length = 5;
+  ranges.push_back (r);
+
+  /* [20, 24] */
+  r.offset = 20;
+  r.length = 5;
+  ranges.push_back (r);
+
+  /* [2, 6] */
+  SELF_CHECK (!ranges_contain (ranges, 2, 5));
+  /* [9, 13] */
+  SELF_CHECK (ranges_contain (ranges, 9, 5));
+  /* [10, 11] */
+  SELF_CHECK (ranges_contain (ranges, 10, 2));
+  /* [10, 14] */
+  SELF_CHECK (ranges_contain (ranges, 10, 5));
+  /* [13, 18] */
+  SELF_CHECK (ranges_contain (ranges, 13, 6));
+  /* [14, 18] */
+  SELF_CHECK (ranges_contain (ranges, 14, 5));
+  /* [15, 18] */
+  SELF_CHECK (!ranges_contain (ranges, 15, 4));
+  /* [16, 19] */
+  SELF_CHECK (!ranges_contain (ranges, 16, 4));
+  /* [16, 21] */
+  SELF_CHECK (ranges_contain (ranges, 16, 6));
+  /* [21, 21] */
+  SELF_CHECK (ranges_contain (ranges, 21, 1));
+  /* [21, 25] */
+  SELF_CHECK (ranges_contain (ranges, 21, 5));
+  /* [26, 28] */
+  SELF_CHECK (!ranges_contain (ranges, 26, 3));
+}
+
+/* Check that RANGES contains the same ranges as EXPECTED.  */
+
+static bool
+check_ranges_vector (gdb::array_view<const range> ranges,
+                    gdb::array_view<const range> expected)
+{
+  return ranges == expected;
+}
+
+/* Test the insert_into_bit_range_vector function.  */
+
+static void
+test_insert_into_bit_range_vector ()
+{
+  std::vector<range> ranges;
+
+  /* [10, 14] */
+  {
+    insert_into_bit_range_vector (&ranges, 10, 5);
+    static const range expected[] = {
+      {10, 5}
+    };
+    SELF_CHECK (check_ranges_vector (ranges, expected));
+  }
+
+  /* [10, 14] */
+  {
+    insert_into_bit_range_vector (&ranges, 11, 4);
+    static const range expected = {10, 5};
+    SELF_CHECK (check_ranges_vector (ranges, expected));
+  }
+
+  /* [10, 14] [20, 24] */
+  {
+    insert_into_bit_range_vector (&ranges, 20, 5);
+    static const range expected[] = {
+      {10, 5},
+      {20, 5},
+    };
+    SELF_CHECK (check_ranges_vector (ranges, expected));
+  }
+
+  /* [10, 14] [17, 24] */
+  {
+    insert_into_bit_range_vector (&ranges, 17, 5);
+    static const range expected[] = {
+      {10, 5},
+      {17, 8},
+    };
+    SELF_CHECK (check_ranges_vector (ranges, expected));
+  }
+
+  /* [2, 8] [10, 14] [17, 24] */
+  {
+    insert_into_bit_range_vector (&ranges, 2, 7);
+    static const range expected[] = {
+      {2, 7},
+      {10, 5},
+      {17, 8},
+    };
+    SELF_CHECK (check_ranges_vector (ranges, expected));
+  }
+
+  /* [2, 14] [17, 24] */
+  {
+    insert_into_bit_range_vector (&ranges, 9, 1);
+    static const range expected[] = {
+      {2, 13},
+      {17, 8},
+    };
+    SELF_CHECK (check_ranges_vector (ranges, expected));
+  }
+
+  /* [2, 14] [17, 24] */
+  {
+    insert_into_bit_range_vector (&ranges, 9, 1);
+    static const range expected[] = {
+      {2, 13},
+      {17, 8},
+    };
+    SELF_CHECK (check_ranges_vector (ranges, expected));
+  }
+
+  /* [2, 33] */
+  {
+    insert_into_bit_range_vector (&ranges, 4, 30);
+    static const range expected = {2, 32};
+    SELF_CHECK (check_ranges_vector (ranges, expected));
+  }
+}
+
+} /* namespace selftests */
+#endif /* GDB_SELF_TEST */
+
 void
 _initialize_values (void)
 {
@@ -3972,4 +4095,9 @@ prevents future values, larger than this size, from being allocated."),
                            set_max_value_size,
                            show_max_value_size,
                            &setlist, &showlist);
+#if GDB_SELF_TEST
+  selftests::register_test ("ranges_contain", selftests::test_ranges_contain);
+  selftests::register_test ("insert_into_bit_range_vector",
+                           selftests::test_insert_into_bit_range_vector);
+#endif
 }
This page took 0.037055 seconds and 4 git commands to generate.