Fix illegal memory accesses trigeered when linking corrupt input files.
[deliverable/binutils-gdb.git] / gdb / linespec.c
index 5f4e95156badb20082445e532940435e3baa4289..7ef8012ab562f628c24e919b462634d055af4c4d 100644 (file)
@@ -80,9 +80,6 @@ enum class linespec_complete_what
 typedef struct symbol *symbolp;
 DEF_VEC_P (symbolp);
 
-typedef struct type *typep;
-DEF_VEC_P (typep);
-
 /* An address entry is used to ensure that any given location is only
    added to the result a single time.  It holds an address and the
    program space from which the address came.  */
@@ -377,10 +374,9 @@ static void add_matching_symbols_to_info (const char *name,
                                          struct collect_info *info,
                                          struct program_space *pspace);
 
-static void add_all_symbol_names_from_pspace (struct collect_info *info,
-                                             struct program_space *pspace,
-                                             VEC (const_char_ptr) *names,
-                                             enum search_domain search_domain);
+static void add_all_symbol_names_from_pspace
+    (struct collect_info *info, struct program_space *pspace,
+     const std::vector<const char *> &names, enum search_domain search_domain);
 
 static VEC (symtab_ptr) *
   collect_symtabs_from_filename (const char *file,
@@ -1211,8 +1207,8 @@ iterate_over_file_blocks
 
 static void
 find_methods (struct type *t, enum language t_lang, const char *name,
-             VEC (const_char_ptr) **result_names,
-             VEC (typep) **superclasses)
+             std::vector<const char *> *result_names,
+             std::vector<struct type *> *superclasses)
 {
   int ibase;
   const char *class_name = type_name_no_tag (t);
@@ -1266,14 +1262,14 @@ find_methods (struct type *t, enum language t_lang, const char *name,
                  if (TYPE_FN_FIELD_STUB (f, field_counter))
                    continue;
                  phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter);
-                 VEC_safe_push (const_char_ptr, *result_names, phys_name);
+                 result_names->push_back (phys_name);
                }
            }
        }
     }
 
   for (ibase = 0; ibase < TYPE_N_BASECLASSES (t); ibase++)
-    VEC_safe_push (typep, *superclasses, TYPE_BASECLASS (t, ibase));
+    superclasses->push_back (TYPE_BASECLASS (t, ibase));
 }
 
 /* Find an instance of the character C in the string S that is outside
@@ -1384,16 +1380,16 @@ find_toplevel_string (const char *haystack, const char *needle)
 }
 
 /* Convert CANONICAL to its string representation using
-   symtab_to_fullname for SYMTAB.  The caller must xfree the result.  */
+   symtab_to_fullname for SYMTAB.  */
 
-static char *
+static std::string
 canonical_to_fullform (const struct linespec_canonical_name *canonical)
 {
   if (canonical->symtab == NULL)
-    return xstrdup (canonical->suffix);
+    return canonical->suffix;
   else
-    return xstrprintf ("%s:%s", symtab_to_fullname (canonical->symtab),
-                      canonical->suffix);
+    return string_printf ("%s:%s", symtab_to_fullname (canonical->symtab),
+                         canonical->suffix);
 }
 
 /* Given FILTERS, a list of canonical names, filter the sals in RESULT
@@ -1402,29 +1398,21 @@ canonical_to_fullform (const struct linespec_canonical_name *canonical)
 static void
 filter_results (struct linespec_state *self,
                std::vector<symtab_and_line> *result,
-               VEC (const_char_ptr) *filters)
+               const std::vector<const char *> &filters)
 {
-  int i;
-  const char *name;
-
-  for (i = 0; VEC_iterate (const_char_ptr, filters, i, name); ++i)
+  for (const char *name : filters)
     {
       linespec_sals lsal;
 
       for (size_t j = 0; j < result->size (); ++j)
        {
          const struct linespec_canonical_name *canonical;
-         char *fullform;
-         struct cleanup *cleanup;
 
          canonical = &self->canonical_names[j];
-         fullform = canonical_to_fullform (canonical);
-         cleanup = make_cleanup (xfree, fullform);
+         std::string fullform = canonical_to_fullform (canonical);
 
-         if (strcmp (name, fullform) == 0)
+         if (name == fullform)
            lsal.sals.push_back ((*result)[j]);
-
-         do_cleanups (cleanup);
        }
 
       if (!lsal.sals.empty ())
@@ -1458,34 +1446,35 @@ convert_results_to_lsals (struct linespec_state *self,
 
 struct decode_line_2_item
 {
-  /* The form using symtab_to_fullname.
-     It must be xfree'ed after use.  */
-  char *fullform;
+  decode_line_2_item (std::string &&fullform_, std::string &&displayform_,
+                     bool selected_)
+    : fullform (std::move (fullform_)),
+      displayform (std::move (displayform_)),
+      selected (selected_)
+  {
+  }
+
+  /* The form using symtab_to_fullname.  */
+  std::string fullform;
 
-  /* The form using symtab_to_filename_for_display.
-     It must be xfree'ed after use.  */
-  char *displayform;
+  /* The form using symtab_to_filename_for_display.  */
+  std::string displayform;
 
   /* Field is initialized to zero and it is set to one if the user
      requested breakpoint for this entry.  */
   unsigned int selected : 1;
 };
 
-/* Helper for qsort to sort decode_line_2_item entries by DISPLAYFORM and
-   secondarily by FULLFORM.  */
+/* Helper for std::sort to sort decode_line_2_item entries by
+   DISPLAYFORM and secondarily by FULLFORM.  */
 
-static int
-decode_line_2_compare_items (const void *ap, const void *bp)
+static bool
+decode_line_2_compare_items (const decode_line_2_item &a,
+                            const decode_line_2_item &b)
 {
-  const struct decode_line_2_item *a = (const struct decode_line_2_item *) ap;
-  const struct decode_line_2_item *b = (const struct decode_line_2_item *) bp;
-  int retval;
-
-  retval = strcmp (a->displayform, b->displayform);
-  if (retval != 0)
-    return retval;
-
-  return strcmp (a->fullform, b->fullform);
+  if (a.displayform != b.displayform)
+    return a.displayform < b.displayform;
+  return a.fullform < b.fullform;
 }
 
 /* Handle multiple results in RESULT depending on SELECT_MODE.  This
@@ -1501,77 +1490,66 @@ decode_line_2 (struct linespec_state *self,
   char *args;
   const char *prompt;
   int i;
-  struct cleanup *old_chain;
-  VEC (const_char_ptr) *filters = NULL;
-  struct decode_line_2_item *items;
-  int items_count;
+  std::vector<const char *> filters;
+  std::vector<struct decode_line_2_item> items;
 
   gdb_assert (select_mode != multiple_symbols_all);
   gdb_assert (self->canonical != NULL);
   gdb_assert (!result->empty ());
 
-  old_chain = make_cleanup (VEC_cleanup (const_char_ptr), &filters);
-
   /* Prepare ITEMS array.  */
-  items_count = result->size ();
-  items = XNEWVEC (struct decode_line_2_item, items_count);
-  make_cleanup (xfree, items);
-  for (i = 0; i < items_count; ++i)
+  for (i = 0; i < result->size (); ++i)
     {
       const struct linespec_canonical_name *canonical;
       struct decode_line_2_item *item;
 
+      std::string displayform;
+
       canonical = &self->canonical_names[i];
       gdb_assert (canonical->suffix != NULL);
-      item = &items[i];
 
-      item->fullform = canonical_to_fullform (canonical);
-      make_cleanup (xfree, item->fullform);
+      std::string fullform = canonical_to_fullform (canonical);
 
       if (canonical->symtab == NULL)
-       item->displayform = canonical->suffix;
+       displayform = canonical->suffix;
       else
        {
          const char *fn_for_display;
 
          fn_for_display = symtab_to_filename_for_display (canonical->symtab);
-         item->displayform = xstrprintf ("%s:%s", fn_for_display,
-                                         canonical->suffix);
-         make_cleanup (xfree, item->displayform);
+         displayform = string_printf ("%s:%s", fn_for_display,
+                                      canonical->suffix);
        }
 
-      item->selected = 0;
+      items.emplace_back (std::move (fullform), std::move (displayform),
+                         false);
     }
 
   /* Sort the list of method names.  */
-  qsort (items, items_count, sizeof (*items), decode_line_2_compare_items);
+  std::sort (items.begin (), items.end (), decode_line_2_compare_items);
 
   /* Remove entries with the same FULLFORM.  */
-  if (items_count >= 2)
-    {
-      struct decode_line_2_item *dst, *src;
-
-      dst = items;
-      for (src = &items[1]; src < &items[items_count]; src++)
-       if (strcmp (src->fullform, dst->fullform) != 0)
-         *++dst = *src;
-      items_count = dst + 1 - items;
-    }
-
-  if (select_mode == multiple_symbols_cancel && items_count > 1)
+  items.erase (std::unique (items.begin (), items.end (),
+                           [] (const struct decode_line_2_item &a,
+                               const struct decode_line_2_item &b)
+                             {
+                               return a.fullform == b.fullform;
+                             }),
+              items.end ());
+
+  if (select_mode == multiple_symbols_cancel && items.size () > 1)
     error (_("canceled because the command is ambiguous\n"
             "See set/show multiple-symbol."));
   
-  if (select_mode == multiple_symbols_all || items_count == 1)
+  if (select_mode == multiple_symbols_all || items.size () == 1)
     {
-      do_cleanups (old_chain);
       convert_results_to_lsals (self, result);
       return;
     }
 
   printf_unfiltered (_("[0] cancel\n[1] all\n"));
-  for (i = 0; i < items_count; i++)
-    printf_unfiltered ("[%d] %s\n", i + 2, items[i].displayform);
+  for (i = 0; i < items.size (); i++)
+    printf_unfiltered ("[%d] %s\n", i + 2, items[i].displayform.c_str ());
 
   prompt = getenv ("PS2");
   if (prompt == NULL)
@@ -1598,13 +1576,12 @@ decode_line_2 (struct linespec_state *self,
             multiple_symbols_all behavior even with the 'ask'
             setting; and he can get separate breakpoints by entering
             "2-57" at the query.  */
-         do_cleanups (old_chain);
          convert_results_to_lsals (self, result);
          return;
        }
 
       num -= 2;
-      if (num >= items_count)
+      if (num >= items.size ())
        printf_unfiltered (_("No choice number %d.\n"), num);
       else
        {
@@ -1612,7 +1589,7 @@ decode_line_2 (struct linespec_state *self,
 
          if (!item->selected)
            {
-             VEC_safe_push (const_char_ptr, filters, item->fullform);
+             filters.push_back (item->fullform.c_str ());
              item->selected = 1;
            }
          else
@@ -1624,7 +1601,6 @@ decode_line_2 (struct linespec_state *self,
     }
 
   filter_results (self, result, filters);
-  do_cleanups (old_chain);
 }
 
 \f
@@ -3185,16 +3161,10 @@ event_location_to_sals (linespec_parser *parser,
 
        if (addr_string != NULL)
          {
-           char *expr = xstrdup (addr_string);
-           const char *const_expr = expr;
-           struct cleanup *cleanup = make_cleanup (xfree, expr);
-
-           addr = linespec_expression_to_pc (&const_expr);
+           addr = linespec_expression_to_pc (&addr_string);
            if (PARSER_STATE (parser)->canonical != NULL)
              PARSER_STATE (parser)->canonical->location
                = copy_event_location (location);
-
-           do_cleanups (cleanup);
          }
 
        result = convert_address_location_to_sals (PARSER_STATE (parser),
@@ -3236,7 +3206,7 @@ decode_line_full (const struct event_location *location, int flags,
                  const char *filter)
 {
   struct cleanup *cleanups;
-  VEC (const_char_ptr) *filters = NULL;
+  std::vector<const char *> filters;
   linespec_parser parser;
   struct linespec_state *state;
 
@@ -3288,8 +3258,7 @@ decode_line_full (const struct event_location *location, int flags,
     {
       if (filter != NULL)
        {
-         make_cleanup (VEC_cleanup (const_char_ptr), &filters);
-         VEC_safe_push (const_char_ptr, filters, filter);
+         filters.push_back (filter);
          filter_results (state, &result, filters);
        }
       else
@@ -3425,20 +3394,19 @@ static std::vector<symtab_and_line>
 decode_objc (struct linespec_state *self, linespec_p ls, const char *arg)
 {
   struct collect_info info;
-  VEC (const_char_ptr) *symbol_names = NULL;
+  std::vector<const char *> symbol_names;
   const char *new_argptr;
-  struct cleanup *cleanup = make_cleanup (VEC_cleanup (const_char_ptr),
-                                         &symbol_names);
 
   info.state = self;
   info.file_symtabs = NULL;
   VEC_safe_push (symtab_ptr, info.file_symtabs, NULL);
-  make_cleanup (VEC_cleanup (symtab_ptr), &info.file_symtabs);
+  struct cleanup *cleanup = make_cleanup (VEC_cleanup (symtab_ptr),
+                                         &info.file_symtabs);
   info.result.symbols = NULL;
   info.result.minimal_symbols = NULL;
 
   new_argptr = find_imps (arg, &symbol_names);
-  if (VEC_empty (const_char_ptr, symbol_names))
+  if (symbol_names.empty ())
     {
       do_cleanups (cleanup);
       return {};
@@ -3664,46 +3632,34 @@ compare_msymbols (const void *a, const void *b)
 static void
 add_all_symbol_names_from_pspace (struct collect_info *info,
                                  struct program_space *pspace,
-                                 VEC (const_char_ptr) *names,
+                                 const std::vector<const char *> &names,
                                  enum search_domain search_domain)
 {
-  int ix;
-  const char *iter;
-
-  for (ix = 0; VEC_iterate (const_char_ptr, names, ix, iter); ++ix)
+  for (const char *iter : names)
     add_matching_symbols_to_info (iter,
                                  symbol_name_match_type::FULL,
                                  search_domain, info, pspace);
 }
 
 static void
-find_superclass_methods (VEC (typep) *superclasses,
+find_superclass_methods (std::vector<struct type *> &&superclasses,
                         const char *name, enum language name_lang,
-                        VEC (const_char_ptr) **result_names)
+                        std::vector<const char *> *result_names)
 {
-  int old_len = VEC_length (const_char_ptr, *result_names);
-  VEC (typep) *iter_classes;
-  struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
+  size_t old_len = result_names->size ();
 
-  iter_classes = superclasses;
   while (1)
     {
-      VEC (typep) *new_supers = NULL;
-      int ix;
-      struct type *t;
+      std::vector<struct type *> new_supers;
 
-      make_cleanup (VEC_cleanup (typep), &new_supers);
-      for (ix = 0; VEC_iterate (typep, iter_classes, ix, t); ++ix)
+      for (struct type *t : superclasses)
        find_methods (t, name_lang, name, result_names, &new_supers);
 
-      if (VEC_length (const_char_ptr, *result_names) != old_len
-         || VEC_empty (typep, new_supers))
+      if (result_names->size () != old_len || new_supers.empty ())
        break;
 
-      iter_classes = new_supers;
+      superclasses = std::move (new_supers);
     }
-
-  do_cleanups (cleanup);
 }
 
 /* This finds the method METHOD_NAME in the class CLASS_NAME whose type is
@@ -3717,11 +3673,10 @@ find_method (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs,
             VEC (bound_minimal_symbol_d) **minsyms)
 {
   struct symbol *sym;
-  struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
   int ix;
-  int last_result_len;
-  VEC (typep) *superclass_vec;
-  VEC (const_char_ptr) *result_names;
+  size_t last_result_len;
+  std::vector<struct type *> superclass_vec;
+  std::vector<const char *> result_names;
   struct collect_info info;
 
   /* Sort symbols so that symbols with the same program space are next
@@ -3745,10 +3700,6 @@ find_method (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs,
      those names.  This loop is written in a somewhat funny way
      because we collect data across the program space before deciding
      what to do.  */
-  superclass_vec = NULL;
-  make_cleanup (VEC_cleanup (typep), &superclass_vec);
-  result_names = NULL;
-  make_cleanup (VEC_cleanup (const_char_ptr), &result_names);
   last_result_len = 0;
   for (ix = 0; VEC_iterate (symbolp, sym_classes, ix, sym); ++ix)
     {
@@ -3773,8 +3724,8 @@ find_method (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs,
        {
          /* If we did not find a direct implementation anywhere in
             this program space, consider superclasses.  */
-         if (VEC_length (const_char_ptr, result_names) == last_result_len)
-           find_superclass_methods (superclass_vec, method_name,
+         if (result_names.size () == last_result_len)
+           find_superclass_methods (std::move (superclass_vec), method_name,
                                     SYMBOL_LANGUAGE (sym), &result_names);
 
          /* We have a list of candidate symbol names, so now we
@@ -3783,8 +3734,8 @@ find_method (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs,
          add_all_symbol_names_from_pspace (&info, pspace, result_names,
                                            FUNCTIONS_DOMAIN);
 
-         VEC_truncate (typep, superclass_vec, 0);
-         last_result_len = VEC_length (const_char_ptr, result_names);
+         superclass_vec.clear ();
+         last_result_len = result_names.size ();
        }
     }
 
@@ -3793,7 +3744,6 @@ find_method (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs,
     {
       *symbols = info.result.symbols;
       *minsyms = info.result.minimal_symbols;
-      do_cleanups (cleanup);
       return;
     }
 
@@ -3929,9 +3879,7 @@ find_function_symbols (struct linespec_state *state,
                       VEC (bound_minimal_symbol_d) **minsyms)
 {
   struct collect_info info;
-  VEC (const_char_ptr) *symbol_names = NULL;
-  struct cleanup *cleanup = make_cleanup (VEC_cleanup (const_char_ptr),
-                                         &symbol_names);
+  std::vector<const char *> symbol_names;
 
   info.state = state;
   info.result.symbols = NULL;
@@ -3940,15 +3888,13 @@ find_function_symbols (struct linespec_state *state,
 
   /* Try NAME as an Objective-C selector.  */
   find_imps (name, &symbol_names);
-  if (!VEC_empty (const_char_ptr, symbol_names))
+  if (!symbol_names.empty ())
     add_all_symbol_names_from_pspace (&info, state->search_pspace,
                                      symbol_names, FUNCTIONS_DOMAIN);
   else
     add_matching_symbols_to_info (name, name_match_type, FUNCTIONS_DOMAIN,
                                  &info, state->search_pspace);
 
-  do_cleanups (cleanup);
-
   if (VEC_empty (symbolp, info.result.symbols))
     {
       VEC_free (symbolp, info.result.symbols);
This page took 0.033528 seconds and 4 git commands to generate.