From ebcb0478f63df3012e75bcf2762b557ce36c1590 Mon Sep 17 00:00:00 2001 From: jakub Date: Fri, 6 Mar 2009 22:49:39 +0000 Subject: [PATCH] PR debug/39372 * dwarf2out.c (add_abstract_origin_attribute): Return origin_die. (gen_variable_die): Emit DW_AT_location on abstract static variable's DIE, don't emit it if abstract origin already has it. * tree-cfg.c (remove_useless_stmts_bind): GIMPLE_BINDs with any BLOCK_NONLOCALIZED_VARS in its gimple_bind_block aren't useless. * g++.dg/debug/dwarf2/static-local-var-in-ctor.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@144682 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 10 ++++++ gcc/dwarf2out.c | 23 +++++++++++--- gcc/testsuite/ChangeLog | 5 +++ .../g++.dg/debug/dwarf2/static-local-var-in-ctor.C | 37 ++++++++++++++++++++++ gcc/tree-cfg.c | 4 +-- 5 files changed, 72 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/debug/dwarf2/static-local-var-in-ctor.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index da40333..f6204bf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2009-03-06 Jakub Jelinek + + PR debug/39372 + * dwarf2out.c (add_abstract_origin_attribute): Return + origin_die. + (gen_variable_die): Emit DW_AT_location on abstract static variable's + DIE, don't emit it if abstract origin already has it. + * tree-cfg.c (remove_useless_stmts_bind): GIMPLE_BINDs with any + BLOCK_NONLOCALIZED_VARS in its gimple_bind_block aren't useless. + 2009-03-06 Jan-Benedict Glaw * genpreds.c: (needs_variable): Fix parentheses at variable name diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 22852fa..63301a5 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -5128,7 +5128,7 @@ static void add_byte_size_attribute (dw_die_ref, tree); static void add_bit_offset_attribute (dw_die_ref, tree); static void add_bit_size_attribute (dw_die_ref, tree); static void add_prototyped_attribute (dw_die_ref, tree); -static void add_abstract_origin_attribute (dw_die_ref, tree); +static dw_die_ref add_abstract_origin_attribute (dw_die_ref, tree); static void add_pure_or_virtual_attribute (dw_die_ref, tree); static void add_src_coords_attributes (dw_die_ref, tree); static void add_name_and_src_coords_attributes (dw_die_ref, tree); @@ -12479,7 +12479,7 @@ add_prototyped_attribute (dw_die_ref die, tree func_type) by looking in either the type declaration or object declaration equate table. */ -static inline void +static inline dw_die_ref add_abstract_origin_attribute (dw_die_ref die, tree origin) { dw_die_ref origin_die = NULL; @@ -12517,7 +12517,8 @@ add_abstract_origin_attribute (dw_die_ref die, tree origin) here. */ if (origin_die) - add_AT_die_ref (die, DW_AT_abstract_origin, origin_die); + add_AT_die_ref (die, DW_AT_abstract_origin, origin_die); + return origin_die; } /* We do not currently support the pure_virtual attribute. */ @@ -13885,6 +13886,7 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die) tree decl_or_origin = decl ? decl : origin; dw_die_ref var_die; dw_die_ref old_die = decl ? lookup_decl_die (decl) : NULL; + dw_die_ref origin_die; int declaration = (DECL_EXTERNAL (decl_or_origin) /* If DECL is COMDAT and has not actually been emitted, we cannot take its address; there @@ -14018,8 +14020,9 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die) var_die = new_die (DW_TAG_variable, context_die, decl); + origin_die = NULL; if (origin != NULL) - add_abstract_origin_attribute (var_die, origin); + origin_die = add_abstract_origin_attribute (var_die, origin); /* Loop unrolling can create multiple blocks that refer to the same static variable, so we must test for the DW_AT_declaration flag. @@ -14082,7 +14085,17 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die) if (decl && (DECL_ABSTRACT (decl) || declaration)) equate_decl_number_to_die (decl, var_die); - if (! declaration && ! DECL_ABSTRACT (decl_or_origin)) + if (! declaration + && (! DECL_ABSTRACT (decl_or_origin) + /* Local static vars are shared between all clones/inlines, + so emit DW_AT_location on the abstract DIE if DECL_RTL is + already set. */ + || (TREE_CODE (decl_or_origin) == VAR_DECL + && TREE_STATIC (decl_or_origin) + && DECL_RTL_SET_P (decl_or_origin))) + /* When abstract origin already has DW_AT_location attribute, no need + to add it again. */ + && (origin_die == NULL || get_AT (origin_die, DW_AT_location) == NULL)) { if (TREE_CODE (decl_or_origin) == VAR_DECL && TREE_STATIC (decl_or_origin) && !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl_or_origin))) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 37c4074..cbc8ae2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-03-06 Jakub Jelinek + + PR debug/39372 + * g++.dg/debug/dwarf2/static-local-var-in-ctor.C: New test. + 2009-03-05 Jason Merrill PR c++/38908 diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/static-local-var-in-ctor.C b/gcc/testsuite/g++.dg/debug/dwarf2/static-local-var-in-ctor.C new file mode 100644 index 0000000..a1bf6b5 --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/dwarf2/static-local-var-in-ctor.C @@ -0,0 +1,37 @@ +// PR debug/39372 +// { dg-do compile } +// { dg-options "-O0 -g -dA" } +// { dg-final { scan-assembler "DW_OP_addr\[^\n\r\]*\[\n\r\]*\[^\n\r\]*staticvar1" } } +// { dg-final { scan-assembler "DW_OP_addr\[^\n\r\]*\[\n\r\]*\[^\n\r\]*staticvar2" } } + +extern void f (int *); + +struct A +{ + A(int i); + void foo(int i); +}; + +A::A(int i) +{ + static int *staticvar1 = new int(i); + f (staticvar1); +} + +void A::foo(int i) +{ + static int *staticvar2 = new int(i); + f (staticvar2); +} + +void f (int *) +{ +} + +int +main (void) +{ + A a(42); + a.foo(42); + return 0; +} diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 440aa93..9c5b2e6 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -1799,11 +1799,11 @@ remove_useless_stmts_bind (gimple_stmt_iterator *gsi, struct rus_data *data ATTR tree var = NULL_TREE; /* Even if there are no gimple_bind_vars, there might be other decls in BLOCK_VARS rendering the GIMPLE_BIND not useless. */ - if (block) + if (block && !BLOCK_NUM_NONLOCALIZED_VARS (block)) for (var = BLOCK_VARS (block); var; var = TREE_CHAIN (var)) if (TREE_CODE (var) == IMPORTED_DECL) break; - if (var) + if (var || (block && BLOCK_NUM_NONLOCALIZED_VARS (block))) gsi_next (gsi); else { -- 2.7.4