This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix debuginfo for static vars in C++ ctors (PR debug/39372)


On Fri, Mar 6, 2009 at 5:38 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> In the testcase below we never emit DW_AT_location for the static variable
> in ctor. ?In the abstract DIE we don't emit it because it is DECL_ABSTRACT
> and in the ctor clone DIEs because the containing GIMPLE_BIND and its BLOCK
> has been nuked during useless pass. ?After fixing this in tree-cfg.c it
> still doesn't work, because the variable in BLOCK_NONLOCALIZED_VARS is still
> DECL_ABSTRACT. ?This patch fixes it by emitting DW_AT_location in the
> abstract DIE when its DECL_RTL has been set already, because the static
> variable is the same between all the clones anyway.
>
> Bootstrapped/regtested on x86_64-linux, ok for trunk?

Ok.

Thanks,
Richard.

> 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.
>
> ? ? ? ?* g++.dg/debug/dwarf2/static-local-var-in-ctor.C: New test.
>
> --- gcc/dwarf2out.c.jj ?2009-03-05 22:14:54.000000000 +0100
> +++ gcc/dwarf2out.c ? ? 2009-03-06 10:40:09.000000000 +0100
> @@ -5128,7 +5128,7 @@ static void add_byte_size_attribute (dw_
> ?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
> ? ?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_re
> ? ? ?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
> ? 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
>
> ? 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
> ? 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)))
> --- gcc/tree-cfg.c.jj ? 2009-03-05 09:44:31.000000000 +0100
> +++ gcc/tree-cfg.c ? ? ?2009-03-05 14:57:46.000000000 +0100
> @@ -1799,11 +1799,11 @@ remove_useless_stmts_bind (gimple_stmt_i
> ? ? ? 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
> ? ? ? ?{
> --- gcc/testsuite/g++.dg/debug/dwarf2/static-local-var-in-ctor.C.jj ? ? 2009-03-06 10:33:57.000000000 +0100
> +++ gcc/testsuite/g++.dg/debug/dwarf2/static-local-var-in-ctor.C ? ? ? ?2009-03-06 10:36:19.000000000 +0100
> @@ -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;
> +}
>
> ? ? ? ?Jakub
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]