diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 29b675d0bc..c8c2b4014d 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2019-07-12 Andrew Burgess + + * dwarf2read.c (read_subrange_index_type): New function. + (read_subrange_type): Move code into new function and call it. + * gdbtypes.c (create_range_type): Add some asserts. + 2019-07-12 Andrew Burgess * dwarf2loc.c (dwarf2_evaluate_property): Change return type, and diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index f4796776db..e918792eab 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -17752,6 +17752,56 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die, return 1; } +/* Read the DW_AT_type attribute for a sub-range. If this attribute is not + present (which is valid) then compute the default type based on the + compilation units address size. */ + +static struct type * +read_subrange_index_type (struct die_info *die, struct dwarf2_cu *cu) +{ + struct type *index_type = die_type (die, cu); + + /* Dwarf-2 specifications explicitly allows to create subrange types + without specifying a base type. + In that case, the base type must be set to the type of + the lower bound, upper bound or count, in that order, if any of these + three attributes references an object that has a type. + If no base type is found, the Dwarf-2 specifications say that + a signed integer type of size equal to the size of an address should + be used. + For the following C code: `extern char gdb_int [];' + GCC produces an empty range DIE. + FIXME: muller/2010-05-28: Possible references to object for low bound, + high bound or count are not yet handled by this code. */ + if (TYPE_CODE (index_type) == TYPE_CODE_VOID) + { + struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile; + struct gdbarch *gdbarch = get_objfile_arch (objfile); + int addr_size = gdbarch_addr_bit (gdbarch) /8; + struct type *int_type = objfile_type (objfile)->builtin_int; + + /* Test "int", "long int", and "long long int" objfile types, + and select the first one having a size above or equal to the + architecture address size. */ + if (int_type && TYPE_LENGTH (int_type) >= addr_size) + index_type = int_type; + else + { + int_type = objfile_type (objfile)->builtin_long; + if (int_type && TYPE_LENGTH (int_type) >= addr_size) + index_type = int_type; + else + { + int_type = objfile_type (objfile)->builtin_long_long; + if (int_type && TYPE_LENGTH (int_type) >= addr_size) + index_type = int_type; + } + } + } + + return index_type; +} + /* Read the given DW_AT_subrange DIE. */ static struct type * @@ -17766,7 +17816,8 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) const char *name; ULONGEST negative_mask; - orig_base_type = die_type (die, cu); + orig_base_type = read_subrange_index_type (die, cu); + /* If ORIG_BASE_TYPE is a typedef, it will not be TYPE_UNSIGNED, whereas the real type might be. So, we use ORIG_BASE_TYPE when creating the range type, but we use the result of check_typedef @@ -17848,45 +17899,6 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) sect_offset_str (die->sect_off), objfile_name (cu->per_cu->dwarf2_per_objfile->objfile)); } - - } - - /* Dwarf-2 specifications explicitly allows to create subrange types - without specifying a base type. - In that case, the base type must be set to the type of - the lower bound, upper bound or count, in that order, if any of these - three attributes references an object that has a type. - If no base type is found, the Dwarf-2 specifications say that - a signed integer type of size equal to the size of an address should - be used. - For the following C code: `extern char gdb_int [];' - GCC produces an empty range DIE. - FIXME: muller/2010-05-28: Possible references to object for low bound, - high bound or count are not yet handled by this code. */ - if (TYPE_CODE (base_type) == TYPE_CODE_VOID) - { - struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile; - struct gdbarch *gdbarch = get_objfile_arch (objfile); - int addr_size = gdbarch_addr_bit (gdbarch) /8; - struct type *int_type = objfile_type (objfile)->builtin_int; - - /* Test "int", "long int", and "long long int" objfile types, - and select the first one having a size above or equal to the - architecture address size. */ - if (int_type && TYPE_LENGTH (int_type) >= addr_size) - base_type = int_type; - else - { - int_type = objfile_type (objfile)->builtin_long; - if (int_type && TYPE_LENGTH (int_type) >= addr_size) - base_type = int_type; - else - { - int_type = objfile_type (objfile)->builtin_long_long; - if (int_type && TYPE_LENGTH (int_type) >= addr_size) - base_type = int_type; - } - } } /* Normally, the DWARF producers are expected to use a signed diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index d7a14b7ace..177455e612 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -914,6 +914,11 @@ create_range_type (struct type *result_type, struct type *index_type, const struct dynamic_prop *low_bound, const struct dynamic_prop *high_bound) { + /* The INDEX_TYPE should be a type capable of holding the upper and lower + bounds, as such a zero sized, or void type makes no sense. */ + gdb_assert (TYPE_CODE (index_type) != TYPE_CODE_VOID); + gdb_assert (TYPE_LENGTH (index_type) > 0); + if (result_type == NULL) result_type = alloc_type_copy (index_type); TYPE_CODE (result_type) = TYPE_CODE_RANGE;