[gdb/symtab] Factor out type::{alloc_fields,copy_fields}

After finding this code in buildsym_compunit::finish_block_internal:
...
              ftype->set_fields
                ((struct field *)
                 TYPE_ALLOC (ftype, nparams * sizeof (struct field)));
...
and fixing PR30810 by using TYPE_ZALLOC, I wondered if there were more
locations that needed fixing.

I decided to make things easier to spot by factoring out a new function
alloc_fields:
...
 /* Allocate the fields array of this type, with NFIELDS elements.  If INIT,
     zero-initialize the allocated memory.  */
  void
  type::alloc_fields (unsigned int nfields, bool init = true);
...
where:
- a regular use would be "alloc_fields (nfields)", and
- an exceptional use that needed no initialization would be
  "alloc_fields (nfields, false)".

Pretty soon I discovered that most of the latter cases are due to
initialization by memcpy, so I added two variants of copy_fields as well.

After this rewrite there are 8 uses of set_fields left:
...
gdb/coffread.c:	  type->set_fields (nullptr);
gdb/coffread.c:	  type->set_fields (nullptr);
gdb/coffread.c:	  type->set_fields (nullptr);
gdb/eval.c:  type->set_fields
gdb/gdbtypes.c:  type->set_fields (args);
gdb/gdbtypes.c:  t->set_fields (XRESIZEVEC (struct field, t->fields (),
gdb/dwarf2/read.c:      type->set_fields (new_fields);
gdb/dwarf2/read.c:	      sub_type->set_fields (sub_type->fields () + 1);
...

These fall into the following categories:
- set to nullptr (coffread.c),
- type not owned by objfile or gdbarch (eval.c), and
- modifying an existing fields array, like adding an element at the end or
  dropping an element at the start (the rest).

Tested on x86_64-linux.
This commit is contained in:
Tom de Vries
2023-08-31 09:37:44 +02:00
parent 0b8b932dce
commit 2774f2dad5
13 changed files with 146 additions and 186 deletions

View File

@@ -1462,14 +1462,9 @@ patch_type (struct type *type, struct type *real_type)
{
struct type *target = type->target_type ();
struct type *real_target = real_type->target_type ();
int field_size = real_target->num_fields () * sizeof (struct field);
target->set_length (real_target->length ());
target->set_num_fields (real_target->num_fields ());
field *fields = (struct field *) TYPE_ALLOC (target, field_size);
memcpy (fields, real_target->fields (), field_size);
target->set_fields (fields);
target->copy_fields (real_target);
if (real_target->name ())
{
@@ -2037,9 +2032,7 @@ coff_read_struct_type (int index, int length, int lastsym,
}
/* Now create the vector of fields, and record how big it is. */
type->set_num_fields (nfields);
type->set_fields
((struct field *) TYPE_ALLOC (type, sizeof (struct field) * nfields));
type->alloc_fields (nfields, false);
/* Copy the saved-up fields into the field vector. */
@@ -2117,9 +2110,7 @@ coff_read_enum_type (int index, int length, int lastsym,
else /* Assume ints. */
type->set_length (gdbarch_int_bit (gdbarch) / TARGET_CHAR_BIT);
type->set_code (TYPE_CODE_ENUM);
type->set_num_fields (nsyms);
type->set_fields
((struct field *) TYPE_ALLOC (type, sizeof (struct field) * nsyms));
type->alloc_fields (nsyms, false);
/* Find the symbols for the values and put them into the type.
The symbols can be found in the symlist that we put them on