Commit 9f0e7885 by Jakub Jelinek Committed by Jakub Jelinek

re PR debug/39372 (Missing DW_AT_location for constructor static variable)

	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.

From-SVN: r144682
parent 3b664bd1
2009-03-06 Jakub Jelinek <jakub@redhat.com>
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 <jbglaw@lug-owl.de> 2009-03-06 Jan-Benedict Glaw <jbglaw@lug-owl.de>
* genpreds.c: (needs_variable): Fix parentheses at variable name * genpreds.c: (needs_variable): Fix parentheses at variable name
......
...@@ -5128,7 +5128,7 @@ static void add_byte_size_attribute (dw_die_ref, tree); ...@@ -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_offset_attribute (dw_die_ref, tree);
static void add_bit_size_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_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_pure_or_virtual_attribute (dw_die_ref, tree);
static void add_src_coords_attributes (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); 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) ...@@ -12479,7 +12479,7 @@ add_prototyped_attribute (dw_die_ref die, tree func_type)
by looking in either the type declaration or object declaration by looking in either the type declaration or object declaration
equate table. */ equate table. */
static inline void static inline dw_die_ref
add_abstract_origin_attribute (dw_die_ref die, tree origin) add_abstract_origin_attribute (dw_die_ref die, tree origin)
{ {
dw_die_ref origin_die = NULL; dw_die_ref origin_die = NULL;
...@@ -12517,7 +12517,8 @@ add_abstract_origin_attribute (dw_die_ref die, tree origin) ...@@ -12517,7 +12517,8 @@ add_abstract_origin_attribute (dw_die_ref die, tree origin)
here. */ here. */
if (origin_die) 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. */ /* 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) ...@@ -13885,6 +13886,7 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die)
tree decl_or_origin = decl ? decl : origin; tree decl_or_origin = decl ? decl : origin;
dw_die_ref var_die; dw_die_ref var_die;
dw_die_ref old_die = decl ? lookup_decl_die (decl) : NULL; dw_die_ref old_die = decl ? lookup_decl_die (decl) : NULL;
dw_die_ref origin_die;
int declaration = (DECL_EXTERNAL (decl_or_origin) int declaration = (DECL_EXTERNAL (decl_or_origin)
/* If DECL is COMDAT and has not actually been /* If DECL is COMDAT and has not actually been
emitted, we cannot take its address; there emitted, we cannot take its address; there
...@@ -14018,8 +14020,9 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die) ...@@ -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); var_die = new_die (DW_TAG_variable, context_die, decl);
origin_die = NULL;
if (origin != 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 /* Loop unrolling can create multiple blocks that refer to the same
static variable, so we must test for the DW_AT_declaration flag. 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) ...@@ -14082,7 +14085,17 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die)
if (decl && (DECL_ABSTRACT (decl) || declaration)) if (decl && (DECL_ABSTRACT (decl) || declaration))
equate_decl_number_to_die (decl, var_die); 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) if (TREE_CODE (decl_or_origin) == VAR_DECL && TREE_STATIC (decl_or_origin)
&& !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl_or_origin))) && !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl_or_origin)))
......
2009-03-06 Jakub Jelinek <jakub@redhat.com>
PR debug/39372
* g++.dg/debug/dwarf2/static-local-var-in-ctor.C: New test.
2009-03-05 Jason Merrill <jason@redhat.com> 2009-03-05 Jason Merrill <jason@redhat.com>
PR c++/38908 PR c++/38908
......
// 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;
}
...@@ -1799,11 +1799,11 @@ remove_useless_stmts_bind (gimple_stmt_iterator *gsi, struct rus_data *data ATTR ...@@ -1799,11 +1799,11 @@ remove_useless_stmts_bind (gimple_stmt_iterator *gsi, struct rus_data *data ATTR
tree var = NULL_TREE; tree var = NULL_TREE;
/* Even if there are no gimple_bind_vars, there might be other /* Even if there are no gimple_bind_vars, there might be other
decls in BLOCK_VARS rendering the GIMPLE_BIND not useless. */ 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)) for (var = BLOCK_VARS (block); var; var = TREE_CHAIN (var))
if (TREE_CODE (var) == IMPORTED_DECL) if (TREE_CODE (var) == IMPORTED_DECL)
break; break;
if (var) if (var || (block && BLOCK_NUM_NONLOCALIZED_VARS (block)))
gsi_next (gsi); gsi_next (gsi);
else else
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment