https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61595
Bug ID: 61595 Summary: Inconsistent DWARF information for arrays of vector types Product: gcc Version: 4.7.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: debug Assignee: unassigned at gcc dot gnu.org Reporter: gcc-bugzilla at mailhell dot seb7.de While writing a DWARF parser/interpreter I hit what seems to be inconsistent DWARF information. The original source for my example originates from "libgcc/config/rs6000/linux-unwind.h" of some older gcc-4.1.0 for powerpc, but I reproduced the issue for the version on my workstation, which is "g++ (SUSE Linux) 4.7.2 20130108 [gcc-4_7-branch revision 195012]" on x86_64. Minimal example c++ code: > struct gcc_vregs > { > __attribute__ ((vector_size (16))) int vr[32]; > }; > > typedef int v4si __attribute__ ((vector_size (16))); > > int main (int argc, char** argv) { > gcc_vregs testData; > for (int i = 0; i < 32; i++) { > v4si x = {i,i+32,i+64,i+96}; > testData.vr[i] = x; > } > > return 0; > } I compiled using "g++ minimal.c -gdwarf-4 -O0 -o minimal" and produced a DWARF output with "objdump minimal -g > minimal.S". The interesting snippet there is the type of gcc_vregs: > <1><25>: Abbrev Number: 2 (DW_TAG_structure_type) > <26> DW_AT_name : (indirect string, offset: 0xd7): gcc_vregs > <2a> DW_AT_byte_size : 512 > <2c> DW_AT_decl_file : 1 > <2d> DW_AT_decl_line : 1 > <2e> DW_AT_sibling : <0x3e> > <2><32>: Abbrev Number: 3 (DW_TAG_member) > <33> DW_AT_name : vr > <36> DW_AT_decl_file : 1 > <37> DW_AT_decl_line : 3 > <38> DW_AT_type : <0x3e> > <3c> DW_AT_data_member_location: 0 > <1><3e>: Abbrev Number: 4 (DW_TAG_array_type) > <3f> DW_AT_type : <0x4e> > <43> DW_AT_sibling : <0x4e> > <2><47>: Abbrev Number: 5 (DW_TAG_subrange_type) > <48> DW_AT_type : <0x5a> > <4c> DW_AT_upper_bound : 31 > <1><4e>: Abbrev Number: 6 (DW_TAG_array_type) > <4f> DW_AT_GNU_vector : 1 > <4f> DW_AT_type : <0x61> > <53> DW_AT_sibling : <0x5a> > <2><57>: Abbrev Number: 7 (DW_TAG_subrange_type) > <58> DW_AT_upper_bound : 3 > <1><5a>: Abbrev Number: 8 (DW_TAG_base_type) > <5b> DW_AT_byte_size : 8 > <5c> DW_AT_encoding : 7 (unsigned) > <5d> DW_AT_name : (indirect string, offset: 0x80): sizetype > <1><61>: Abbrev Number: 9 (DW_TAG_base_type) > <62> DW_AT_byte_size : 4 > <63> DW_AT_encoding : 5 (signed) > <64> DW_AT_name : int As you can see, the total size of gcc_vregs is 512 bytes. Running the code in gdb and examining main memory prior to the return statement verifies that the variable testData contains 128 values, each being a 4 byte integer (see testData.txt in the appended tar for a hexdump of its memory region). The DW_AT_type of its member vr is 0x4e, which is an array (or, in fact, a vector) containing four sizetype's of size 8 bytes each. So in total a child of vr is 4*8 = 32 bytes large. Using this information, the total size is <array element count> * 32 bytes. Since there is just one subrange of size 32, the element count is 32 and thus the total size should be 1024 bytes. On the other hand, the 32 element subrange of vr has the type 0x5a. This is the 'sizetype' of size 8 bytes. So each of the subrange elements should be 8 bytes small, and the computed size of the array vr (ignoring its own DW_AT_type) is 8 bytes * 32 = 256. As you can see, both ways compute a different size. While it is possible they differ, usually a small DW_TAG_array_types' DW_AT_type is stored in a bigger DW_TAG_subrange_type's DW_AT_type. I.e. a 'unsigned char[16]' could store each char (of size 1) in an unsigned int (of size 4) due to alignment restrictions. But the code generated here is completely off, since the size is definitely 512 bytes (32 Elements in the array, each element is vector of four 4 byte ints -> 32 * 4 * 4 Bytes = 512 Bytes; verified against binaries behaviour). Expected: * The DW_TAG_base_type at 0x5a should be unsigned int with a DW_AT_byte_size of 4. * The DW_TAG_subrange_type at 0x47 should be of type 0x4e -> it's a subrange containing 32 elements, which are themselfs vectors of four 4 byte integer values. I append a tarball containing * minimal.c - my minimal example source code * minimal.S - DWARF information * testData.txt - a memory dump of the variable 'testData' prior to the return. I don't know about the policy for binaries, so I didn't attach it. But I can still do so, if that is required.