Summary: | C block scopes have no DW_TAG_lexical_block | ||
---|---|---|---|
Product: | gcc | Reporter: | Jan Kratochvil <jkratochvil> |
Component: | debug | Assignee: | Jakub Jelinek <jakub> |
Status: | RESOLVED FIXED | ||
Severity: | minor | CC: | dodji, gcc-bugs, jakub, jsm28 |
Priority: | P3 | ||
Version: | 4.4.0 | ||
Target Milestone: | --- | ||
Host: | Target: | x86_64-unknown-linux-gnu | |
Build: | Known to work: | ||
Known to fail: | Last reconfirmed: | 2009-03-27 12:38:16 | |
Attachments: |
gcc44-pr39563.patch
gcc44-pr39563.patch gcc44-pr39563.patch |
Description
Jan Kratochvil
2009-03-26 17:12:27 UTC
As DW_AT_external-DW_TAG_variable in the inner block is incompatible with current GDB http://sourceware.org/ml/gdb-patches/2009-03/msg00595.html the current C++ method of DW_TAG_imported_declaration referencing the file-level DW_AT_external-DW_TAG_variable may be more appropriate. This seems to be just a C FE problem, C++ FE compiling the exact same testcase gives the expected output (DW_TAG_lexical_block with DW_TAG_variable with DW_AT_external). So IMHO just the C FE should be fixed to handle it like the C++ FE and if there are gdb bugs, they should be fixed in gdb. Created attachment 17544 [details] gcc44-pr39563.patch Untested fix. The problem with this patch is that DW_AT_decl_file and DW_AT_decl_line of the DW_AT_external DW_TAG_variable and DW_TAG_subprogram DIEs is wrong. Say for: extern void abort (void); int var = 1; int main (void) { int var = 2; if (var != 2) abort (); { extern int var; extern void abort (void); if (var != 1) abort (); { int var = 3; if (var != 3) abort (); { extern int var; extern void abort (void); if (var != 1) abort (); } } } return 0; } for all DW_AT_external DW_TAG_variable DIEs DW_AT_decl_line is 3 and for abort DW_AT_decl_line is the last extern void abort (void) line. Created attachment 17547 [details] gcc44-pr39563.patch Updated patch that preserves the correct location info for the nested extern decls. Created attachment 17548 [details] gcc44-pr39563.patch Patch that actually bootstrapped/regtested successfully. Jan, could you please test it with gdb/archer? No regressions for GDB. GDB requires the extra patch otherwise it still does not work with patched GCC: http://sourceware.org/ml/gdb-patches/2009-03/msg00595.html FYI the patch generates one extra file-scope declaration: int f (void) { extern int var; return var; } < c> DW_AT_producer : (indirect string, offset: 0x0): GNU C 4.5.0 20090328 (experimental) <1><2d>: Abbrev Number: 2 (DW_TAG_subprogram) <2f> DW_AT_name : f [...] <2><50>: Abbrev Number: 3 (DW_TAG_variable) <51> DW_AT_name : var <55> DW_AT_decl_file : 1 <56> DW_AT_decl_line : 1 <57> DW_AT_type : <0x5e> <5b> DW_AT_external : 1 <5c> DW_AT_declaration : 1 [...] <1><65>: Abbrev Number: 3 (DW_TAG_variable) <66> DW_AT_name : var <6a> DW_AT_decl_file : 1 <6b> DW_AT_decl_line : 1 <6c> DW_AT_type : <0x5e> <70> DW_AT_external : 1 <71> DW_AT_declaration : 1 Subject: Bug 39563 Author: jakub Date: Mon Mar 30 14:35:03 2009 New Revision: 145293 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=145293 Log: PR debug/39563 * c-decl.c (struct c_binding): Add locus field. (bind): Add locus argument, set locus field from it. (pop_scope): For b->nested VAR_DECL or FUNCTION_DECL, add a DECL_EXTERNAL copy of b->decl to current BLOCK_VARS. (push_file_scope, pushtag, pushdecl, pushdecl_top_level, implicitly_declare, undeclared_variable, lookup_label, declare_label, c_make_fname_decl, c_builtin_function, c_builtin_function_ext_scope, store_parm_decls_newstyle): Adjust bind callers. Modified: trunk/gcc/ChangeLog trunk/gcc/c-decl.c Fixed on the trunk. Fixed in FSF GDB HEAD: http://sourceware.org/ml/gdb-patches/2009-03/threads.html#00595 http://sourceware.org/ml/gdb-patches/2009-04/threads.html#00040 http://sourceware.org/ml/gdb-cvs/2009-04/msg00021.html gdb/ * dwarf2read.c (new_symbol <DW_TAG_variable> <!DW_AT_location> <DW_AT_external>): Create the symbol in local scope. * symtab.h (cu->list_in_scope <LOC_UNRESOLVED>): New comment part. gdb/testsuite/ * gdb.dwarf2/dw2-unresolved-main.c, gdb.dwarf2/dw2-unresolved.S, gdb.dwarf2/dw2-unresolved.exp: New. |