This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH 2/2] handle VLA in a struct or union


> > On May 8, 2014, at 11:46 AM, Tom Tromey <tromey@redhat.com> wrote:
> > 
> >   return 0;
> > @@ -1753,6 +1767,86 @@ resolve_dynamic_type (struct type *type, CORE_ADDR addr)
> >       case TYPE_CODE_RANGE:
> >    resolved_type = resolve_dynamic_range (type);
> >    break;
> > +
> > +    case TYPE_CODE_UNION:
> > +      {
> > +    int i;
> > +    unsigned int max_len;
Shouldn't max_len be initialised to 0 to start with ?

> > +
> > +    resolved_type = copy_type (type);
> > +    TYPE_FIELDS (resolved_type)
> > +      = TYPE_ALLOC (resolved_type,
> > +            TYPE_NFIELDS (resolved_type) * sizeof (struct field));
> > +    memcpy (TYPE_FIELDS (resolved_type),
> > +        TYPE_FIELDS (type),
> > +        TYPE_NFIELDS (resolved_type) * sizeof (struct field));
> > +    for (i = 0; i < TYPE_NFIELDS (resolved_type); ++i)
> > +      {
> > +        struct type *t;
> > +
> > +        if (field_is_static (&TYPE_FIELD (type, i)))
> > +          continue;
> > +
> > +        t = resolve_dynamic_type (TYPE_FIELD_TYPE (resolved_type, i),
> > +                      addr);
> > +
> > +        TYPE_FIELD_TYPE (resolved_type, i) = t;
> > +        if (TYPE_LENGTH (t) > max_len)
> > +          max_len = TYPE_LENGTH (t);
> > +      }
> > +
> > +    TYPE_LENGTH (resolved_type) = max_len;
> > +      }
> > +      break;
> > +
> > +    case TYPE_CODE_STRUCT:
> > +      {
> > +    int i;
> > +    int vla_field = TYPE_NFIELDS (type) - 1;
> > +
> > +    resolved_type = copy_type (type);
> > +    TYPE_FIELDS (resolved_type)
> > +      = TYPE_ALLOC (resolved_type,
> > +            TYPE_NFIELDS (resolved_type) * sizeof (struct field));
> > +    memcpy (TYPE_FIELDS (resolved_type),
> > +        TYPE_FIELDS (type),
> > +        TYPE_NFIELDS (resolved_type) * sizeof (struct field));
> > +    for (i = 0; i < TYPE_NFIELDS (resolved_type); ++i)
> > +      {
> > +        struct type *t;
> > +
> > +        if (field_is_static (&TYPE_FIELD (type, i)))
> > +          continue;
> > +
> > +        t = resolve_dynamic_type (TYPE_FIELD_TYPE (resolved_type, i),
> > +                      addr);
> > +
> > +        /* This is a bit odd.  We do not support a VLA in any
> > +           position of a struct except for the last.  GCC does
> > +           have an extension that allows a VLA in the middle of a
> > +           structure, but the DWARF it emits is relatively useless
> > +           to us, so we can't represent such a type properly --
> > +           and even if we could, we do not have enough information
> > +           to redo structure layout anyway.  Nevertheless, we
> > +           check all the fields in case something odd slips
> > +           through, since it's better to see an error than
> > +           incorrect results.  */
> > +        if (t != TYPE_FIELD_TYPE (resolved_type, i)
> > +        && i != vla_field)
> > +          error (_("Attempt to resolve a variably-sized type which appears "
> > +               "in the interior of a structure type"));
> > +
> > +        TYPE_FIELD_TYPE (resolved_type, i) = t;
> > +      }
> > +
> > +    /* Due to the above restrictions we can successfully compute
> > +       the size of the resulting structure here, as the offset of
> > +       the final field plus its size.  */
> > +    TYPE_LENGTH (resolved_type)
> > +      = (TYPE_FIELD_BITPOS (resolved_type, vla_field) / TARGET_CHAR_BIT
> > +         + TYPE_LENGTH (TYPE_FIELD_TYPE (resolved_type, vla_field)));
> > +      }
> > +      break;
> >     }
> > 
> >   return resolved_type;
> > diff --git a/gdb/testsuite/gdb.base/vla-datatypes.c b/gdb/testsuite/gdb.base/vla-datatypes.c
> > index 51e342e..8561a4e 100644
> > --- a/gdb/testsuite/gdb.base/vla-datatypes.c
> > +++ b/gdb/testsuite/gdb.base/vla-datatypes.c
> > @@ -46,6 +46,18 @@ vla_factory (int n)
> >   BAR             bar_vla[n];
> >   int i;
> > 
> > +  struct vla_struct
> > +  {
> > +    int something;
> > +    int vla_field[n];
> > +  } vla_struct_object;
> > +
> > +  union vla_union
> > +  {
> > +    int vla_field[n];
> > +  } vla_union_object;
> > +
> > +  vla_struct_object.something = n;
> >   for (i = 0; i < n; i++)
> >     {
> >       int_vla[i] = i*2;
> > @@ -61,6 +73,8 @@ vla_factory (int n)
> >       foo_vla[i].a = i*2;
> >       bar_vla[i].x = i*2;
> >       bar_vla[i].y.a = i*2;
> > +      vla_struct_object.vla_field[i] = i*2;
> > +      vla_union_object.vla_field[i] = i*2;
> >     }
> > 
> >   size_t int_size        = sizeof(int_vla);     /* vlas_filled */
> > @@ -74,6 +88,8 @@ vla_factory (int n)
> >   size_t uchar_size      = sizeof(unsigned_char_vla);
> >   size_t foo_size        = sizeof(foo_vla);
> >   size_t bar_size        = sizeof(bar_vla);
> > +  size_t vla_struct_object_size = sizeof(vla_struct_object);
> > +  size_t vla_union_object_size = sizeof(vla_union_object);
> > 
> >   return;                                 /* break_end_of_vla_factory */
> > }
> > diff --git a/gdb/testsuite/gdb.base/vla-datatypes.exp b/gdb/testsuite/gdb.base/vla-datatypes.exp
> > index 8247658..36af38d 100644
> > --- a/gdb/testsuite/gdb.base/vla-datatypes.exp
> > +++ b/gdb/testsuite/gdb.base/vla-datatypes.exp
> > @@ -53,6 +53,10 @@ gdb_test "print foo_vla" \
> > gdb_test "print bar_vla" \
> >          "\\\{\\\{x = 0, y = \\\{a = 0\\\}\\\}, \\\{x = 2, y = \\\{a = 2\\\}\\\}, \\\{x = 4, y = \\\{a = 4\\\}\\\}, \\\{x = 6, y = \\\{a = 6\\\}\\\}, \\\{x = 8, y = \\\{a = 8\\\}\\\}\\\}" \
> >          "print bar_vla"
> > +gdb_test "print vla_struct_object" \
> > +    "\\\{something = 5, vla_field = \\\{0, 2, 4, 6, 8\\\}\\\}"
> > +gdb_test "print vla_union_object" \
> > +    "\\\{vla_field = \\\{0, 2, 4, 6, 8\\\}\\\}"
> > 
> > # Check whatis of VLA's.
> > gdb_test "whatis int_vla" "type = int \\\[5\\\]" "whatis int_vla"
> > @@ -74,6 +78,8 @@ gdb_test "whatis unsigned_char_vla" "type = unsigned char \\\[5\\\]" \
> >          "whatis unsigned_char_vla"
> > gdb_test "whatis foo_vla" "type = struct foo \\\[5\\\]" "whatis foo_vla"
> > gdb_test "whatis bar_vla" "type = BAR \\\[5\\\]" "whatis bar_vla"
> > +gdb_test "whatis vla_struct_object" "type = struct vla_struct"
> > +gdb_test "whatis vla_union_object" "type = union vla_union"
> > 
> > # Check ptype of VLA's.
> > gdb_test "ptype int_vla" "type = int \\\[5\\\]" "ptype int_vla"
> > @@ -96,6 +102,10 @@ gdb_test "ptype foo_vla" "type = struct foo {\r\n\\s+int a;\r\n} \\\[5\\\]" \
> > gdb_test "ptype bar_vla" \
> >          "type = struct bar {\r\n\\s+int x;\r\n\\s+struct foo y;\r\n} \\\[5\\\]" \
> >          "ptype bar_vla"
> > +gdb_test "ptype vla_struct_object" \
> > +    "type = struct vla_struct {\r\n\\s+int something;\r\n\\s+int vla_field\\\[5\\\];\r\n}"
> > +gdb_test "ptype vla_union_object" \
> > +    "type = union vla_union {\r\n\\s+int vla_field\\\[5\\\];\r\n}"
> > 
> > # Check the size of the VLA's.
> > gdb_breakpoint [gdb_get_line_number "break_end_of_vla_factory"]
> > @@ -119,6 +129,10 @@ gdb_test "print uchar_size == sizeof(unsigned_char_vla)" " = 1" \
> >          "size of unsigned_char_vla"
> > gdb_test "print foo_size == sizeof(foo_vla)" " = 1" "size of foo_vla"
> > gdb_test "print bar_size == sizeof(bar_vla)" " = 1" "size of bar_vla"
> > +gdb_test "print vla_struct_object_size == sizeof(vla_struct_object)" \
> > +    " = 1" "size of vla_struct_object"
> > +gdb_test "print vla_union_object_size == sizeof(vla_union_object)" \
> > +    " = 1" "size of vla_union_object"
> > 
> > # Check side effects for sizeof argument.
> > set sizeof_int [get_sizeof "int" 4]
> > -- 
> > 1.9.0
> > 



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]