Gcc emits dwarf which has the const qualifier replicated in this test Release: 3.2 Environment: System: Linux pc4 2.4.18 #1 Tue Apr 2 10:17:01 BST 2002 i686 unknown Architecture: i686 host: i686-pc-linux-gnu build: i686-pc-linux-gnu target: i686-pc-linux-gnu configured with: /home1/GNU/gcc-3.2/configure How-To-Repeat: ------------------ horrible.c ---------------- typedef int twenty_ints[20]; twenty_ints const const_twenty_array; twenty_ints twenty_twenty_array[20]; twenty_ints const const_twenty_twenty_array[20]; int main (int argc, char ** argv) { int i = const_twenty_twenty_array[1][1]; } ---------------------------------------------- % gcc -g -o horrible horrible.c % readelf -wi horrible The section .debug_info contains: Compilation Unit @ 0: Length: 291 Version: 2 Abbrev Offset: 0 Pointer Size: 4 <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit) DW_AT_stmt_list : 0 DW_AT_high_pc : 0x804839a 134513562 DW_AT_low_pc : 0x8048380 134513536 DW_AT_name : (indirect string, offset: 0x39): horrible.c DW_AT_comp_dir : (indirect string, offset: 0x1e): /home1/jim/tmp DW_AT_producer : (indirect string, offset: 0x0): GNU C 3.2 DW_AT_language : 1 (ANSI C) <1><25>: Abbrev Number: 2 (DW_TAG_subprogram) DW_AT_sibling : <69> DW_AT_external : 1 DW_AT_name : (indirect string, offset: 0x14): main DW_AT_decl_file : 1 DW_AT_decl_line : 9 DW_AT_prototyped : 1 DW_AT_type : <69> DW_AT_low_pc : 0x8048380 134513536 DW_AT_high_pc : 0x804839a 134513562 DW_AT_frame_base : 1 byte block: 55 (DW_OP_reg5; ) <2><40>: Abbrev Number: 3 (DW_TAG_formal_parameter) DW_AT_name : (indirect string, offset: 0xa): argc DW_AT_decl_file : 1 DW_AT_decl_line : 8 DW_AT_type : <69> DW_AT_location : 2 byte block: 91 8 (DW_OP_fbreg: 8; ) <2><4e>: Abbrev Number: 3 (DW_TAG_formal_parameter) DW_AT_name : (indirect string, offset: 0xf): argv DW_AT_decl_file : 1 DW_AT_decl_line : 8 DW_AT_type : <70> DW_AT_location : 2 byte block: 91 c (DW_OP_fbreg: 12; ) <2><5c>: Abbrev Number: 4 (DW_TAG_variable) DW_AT_name : i DW_AT_decl_file : 1 DW_AT_decl_line : 10 DW_AT_type : <69> DW_AT_location : 2 byte block: 91 7c (DW_OP_fbreg: -4; ) <1><69>: Abbrev Number: 5 (DW_TAG_base_type) DW_AT_name : int DW_AT_byte_size : 4 DW_AT_encoding : 5 (signed) <1><70>: Abbrev Number: 6 (DW_TAG_pointer_type) DW_AT_byte_size : 4 DW_AT_type : <76> <1><76>: Abbrev Number: 6 (DW_TAG_pointer_type) DW_AT_byte_size : 4 DW_AT_type : <7c> <1><7c>: Abbrev Number: 7 (DW_TAG_base_type) DW_AT_name : (indirect string, offset: 0x19): char DW_AT_byte_size : 1 DW_AT_encoding : 6 (signed char) <1><83>: Abbrev Number: 8 (DW_TAG_typedef) DW_AT_name : (indirect string, offset: 0x2d): twenty_ints DW_AT_decl_file : 1 DW_AT_decl_line : 1 DW_AT_type : <8e> <1><8e>: Abbrev Number: 9 (DW_TAG_array_type) DW_AT_sibling : <9e> DW_AT_type : <69> <2><97>: Abbrev Number: 10 (DW_TAG_subrange_type) DW_AT_type : <9e> DW_AT_upper_bound : 19 <1><9e>: Abbrev Number: 7 (DW_TAG_base_type) DW_AT_name : (indirect string, offset: 0x44): unsigned int DW_AT_byte_size : 4 DW_AT_encoding : 7 (unsigned) <1><a5>: Abbrev Number: 9 (DW_TAG_array_type) DW_AT_sibling : <b5> DW_AT_type : <b5> <2><ae>: Abbrev Number: 10 (DW_TAG_subrange_type) DW_AT_type : <9e> DW_AT_upper_bound : 19 <1><b5>: Abbrev Number: 11 (DW_TAG_const_type) DW_AT_type : <69> <1><ba>: Abbrev Number: 12 (DW_TAG_variable) DW_AT_name : (indirect string, offset: 0x6b): const_twenty_array DW_AT_decl_file : 1 DW_AT_decl_line : 3 DW_AT_type : <cc> DW_AT_external : 1 DW_AT_location : 5 byte block: 3 20 95 4 8 (DW_OP_addr: 8049520; ) <1><cc>: Abbrev Number: 11 (DW_TAG_const_type) DW_AT_type : <a5> <1><d1>: Abbrev Number: 9 (DW_TAG_array_type) DW_AT_sibling : <e7> DW_AT_type : <69> <2><da>: Abbrev Number: 10 (DW_TAG_subrange_type) DW_AT_type : <9e> DW_AT_upper_bound : 19 <2><e0>: Abbrev Number: 10 (DW_TAG_subrange_type) DW_AT_type : <9e> DW_AT_upper_bound : 19 <1><e7>: Abbrev Number: 12 (DW_TAG_variable) DW_AT_name : (indirect string, offset: 0x57): twenty_twenty_array DW_AT_decl_file : 1 DW_AT_decl_line : 4 DW_AT_type : <d1> DW_AT_external : 1 DW_AT_location : 5 byte block: 3 c0 9b 4 8 (DW_OP_addr: 8049bc0; ) <1><f9>: Abbrev Number: 9 (DW_TAG_array_type) DW_AT_sibling : <10f> DW_AT_type : <b5> <2><102>: Abbrev Number: 10 (DW_TAG_subrange_type) DW_AT_type : <9e> DW_AT_upper_bound : 19 <2><108>: Abbrev Number: 10 (DW_TAG_subrange_type) DW_AT_type : <9e> DW_AT_upper_bound : 19 <1><10f>: Abbrev Number: 12 (DW_TAG_variable) DW_AT_name : (indirect string, offset: 0x51): const_twenty_twenty_array DW_AT_decl_file : 1 DW_AT_decl_line : 6 DW_AT_type : <121> DW_AT_external : 1 DW_AT_location : 5 byte block: 3 80 95 4 8 (DW_OP_addr: 8049580; ) <1><121>: Abbrev Number: 11 (DW_TAG_const_type) DW_AT_type : <f9> % Observe that the type of const_twenty_twenty_array is <121> which is Const type <f9> <f9> is an array of type <b5> <b5> is const type <69> so the type is described with two const qualifiers, which is wrong, there is only one const qualifier in the source and there should only be one in the DWARF. Unformatted: >code.
Fix: Kill one of the const qualifiers.
Targeting to 3.4 to get on the radar... Could someone who understands 'const' in C and/or DWARF better than me confirm that this behavior is, in fact, a bug? I can confirm that the behavior is the same in mainline (will be 3.4).
Confirmed.
really confirmed, ICC 6.0 does not produce the extra DW_TAG_const_type and also this is not a regression.
One more thing, a type def is not needed: int const ii[20][20]; will produce the extra DW_TAG_const_type.
Patch : http://gcc.gnu.org/ml/gcc-patches/2004-02/msg00030.html
See http://gcc.gnu.org/ml/gcc-patches/2004-02/msg01911.html for patch review.
http://gcc.gnu.org/ml/gcc-patches/2004-02/msg01911.html seems to be the wrong reference (it's about loop peeling).
Here is the corrected link http://gcc.gnu.org/ml/gcc-patches/2004-02/msg01995.html or follow the link to the patch and click on followups.
Created attachment 12702 [details] PR/8354 patch discussion thread As reported in Bug #20588, the referenced links to the gcc-patch mailing list archives are broken. The referenced mail messages are included in this attachment.
I looked into fixing GCC's DWARF 2 generation for types that are qualified (for example, "const" and "volatile", and in the case of UPC, "shared", "strict", and "relaxed") in order to ensure that GDB has an accurate understanding of when a particular object's type is qualified: http://sourceware.org/ml/gdb/2006-11/msg00185.html http://sourceware.org/ml/gdb/2006-12/msg00133.html http://sourceware.org/ml/gdb/2006-12/msg00177.html In the latter e-mail reply, copied below, I sketched out three possible ways to fix the DWARF 2 information that GCC presently generates for qualified types. It would be great if someone familiar with the GCC front-end reviews my analysis, and either corrects it, or improves upon the suggested approaches. Additionally, I'm a bit unsure on what the "correct" DWARF 2 information should look like in all cases. For example should the members/fields of a struct/union that is C-V qualified also be individually qualified? One commercial compiler that I tried did not do this. Alternatively, would all the possible DWARF 2 type qualifier representation issues best be handled within GDB? This would move the problem from GCC back to GDB, and at the same time improve upon inter-operability. --- copy of http://sourceware.org/ml/gdb/2006-12/msg00177.html --- Jim Blandy wrote: > > "Gary Funck" <gary@intrepid.com> writes: > > The main difficulty is that GCC doesn't create new qualified > > types for declarations. Rather, it sets TREE_READONLY() > > and TREE_THIS_VOLATILE() in the DECL node for declarations > > such as: > > > > volatile int A[10]; > > Ugh. That's a shame. Can't dwarf2out.c fix things up as it builds > the tree of struct die_structs from the GCC 'tree' type tree? In theory, it should be possible. I worked on this a bit, but I think to do it right, this fix will require contribution/direction from someone more conversant in the GCC front-end, and more knowledgeable about how the other language front-ends use both the DWARF 2 generation routines, and the extent to which they depend upon the type information remaining in its current form. Three approaches to fixing the front end to create appropriate DWARF 2 information come to mind: (1) Change the GCC front-end, so that when it creates type information and associates the type information with a declaration that it fully qualifies the type definition, in a way that preserves language semantics, yet also ensures that the correct DWARF 2 information is generated for qualified types. (2) Create the fully qualified type definition in dwarf2out.c (probably in routines that handle DECL items such as gen_formal_parameter_die(), gen_variable_die() and gen_field_die()). There are two likely sub-approaches: (i) keep this fully qualified type definition on the side, parallel to the existing type definition structure, or (ii) smash the new fully qualified type into the DECL node's TREE_TYPE() value. Keeping a parallel definition may be difficult because various parts of dwarfout.c may need to refer back to the DECL node's type value, and all places that do this will have to be found and fixed. Cross-type references and typedef's create another set of problems. Rewriting the declaration's type value is the most straightforward, but runs the risk of violating various assumptions made by the language front-ends, and will require a rather elaborate "deep copy" mechanism to make sure the fix up is done correctly. (3) Run a final pass over the internal DWARF tree built within dwarfout.c to fix up the type qualifiers, basically propagating the const_ and volatile_ qualifiers down to lower levels as required. This is probably doable, but will slow down DWARF generation for all compilations, even if most compilations seldom use "const" and "volatile" (and other qualifiers, such as UPC's "shared", "strict", and "relaxed"). In this case, it seems that dwarf2out.c is fixing representation issues that more correctly should be solved in the front-end. Given the tradeoffs, choice (1) above, where the type description is fully qualified at the time the type is bound to the DECL item, seems more correct, but may impact the correct operation of the various language front-ends and therefore will require more care and more study. Choice (2) is perhaps a bad compromise, and choice (3) is likely workable, but kludgy.
Jim Wilson posted thi follow up to the GDB list: http://sourceware.org/ml/gdb/2007-01/msg00007.html From: Jim Wilson <wilson at specifix dot com> Date: Mon, 01 Jan 2007 14:15:47 -0800 Subject: RE: how to support C type qualifiers applied to arrays? On Thu, 2006-12-14 at 12:22 -0800, Gary Funck wrote: > The main difficulty is that GCC doesn't create new qualified > types for declarations. Rather, it sets TREE_READONLY() > and TREE_THIS_VOLATILE() in the DECL node for declarations > such as: > volatile int A[10]; If you look at the types created by the C front end, they are OK. c_build_qualified_type knows how to handle an array correctly. The problem arises in the DWARF2 output code. gen_type_die calls type_main_variant for all types other than vector types, which strips off the const and volatile type modifiers. Then it clumsily tries to put them back later in gen_variable_die, except that for array types, it puts them back in the wrong place. This seems to answer the question I asked long ago. Why are we trying to put back qualifiers from the decl? Because gen_type_die stripped them off. This seems wrong. If we fix gen_type_die to stop calling type_main_variant, and if we fix gen_variable_die to stop adding back the type qualifiers, then I get the right result. So I think I was on the right track before, we just need another little change to gen_type_die in addition to what I already described. I haven't investigated this in detail yet. There may be other parts of the code that expect to see a type main variant here, so we might need other cascading fixes. This still seems fixable to me though.
http://sourceware.org/ml/gdb/2007-01/msg00147.html From: "Gary Funck" <gary at intrepid dot com> To: <gdb at sourceware dot org> Date: Tue, 9 Jan 2007 09:01:38 -0800 Subject: RE: how to support C type qualifiers applied to arrays? Jim Wilson wrote (in part): > This seems to answer the question I asked long ago. Why are we trying > to put back qualifiers from the decl? Because gen_type_die stripped > them off. This seems wrong. > It seems that the use of type_main_variant() dates back to the original port of the DWARF 1 generator to the DWARF 2 implementation. I didn't try understanding the DWARF 1 generator in detail, but it seemed that the use of the type's main variant helped limit the number of unique type dies that were generated. In any event, it doesn't appear that there is a compelling reason to continue to use the type_main_variant() for DWARF 2 generatiion, especially in light of the fact that in some cases the DWARF 2 information is incorrect in the current implmentation. There are of course the risks that you mentioned in your reply that there may now be implicit assumptions made by the various clients (C, C++, Fortran, Ada, for example) regarding dependencies upon the type_main_variant(), but we may have to deal with those issues as they arise. > If we fix gen_type_die to stop calling type_main_variant, and > if we fix > gen_variable_die to stop adding back the type qualifiers, > then I get the > right result. So I think I was on the right track before, we > just need > another little change to gen_type_die in addition to what I already > described. I'll give this a try, and follow up.