Bug 47510 - DW_TAG_typedef can have children when designating a naming typedef
Summary: DW_TAG_typedef can have children when designating a naming typedef
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: debug (show other bugs)
Version: 4.6.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks: 48603
  Show dependency treegraph
 
Reported: 2011-01-28 11:08 UTC by Dodji Seketeli
Modified: 2012-03-04 18:30 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2011-03-16 21:30:27


Attachments
Candidate patch (1.58 KB, patch)
2011-01-28 11:13 UTC, Dodji Seketeli
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Dodji Seketeli 2011-01-28 11:08:53 UTC
Consider this test case:

    class C {
    public:
      C() {}
      ~C() {}
    };
    typedef struct {
      C m;
    } t;
    typedef t s;
    s v;

The DW_TAG_typedef DIE describing the typedef t has children DIEs. The
children DIEs are actually the DIEs representing the members of the
anonymous structure named by T.

What is happening is, since gen_typedef_die equates the anonymous
struct named by the typedef t with the DIE of the naming typedef,
get_context_die called with the type tree of the anonymous typedef
yields the DIE of the typedef.
Comment 1 Dodji Seketeli 2011-01-28 11:13:51 UTC
Created attachment 23149 [details]
Candidate patch

I am bootstrapping this patch at the moment.
Comment 2 Dodji Seketeli 2011-01-28 16:13:07 UTC
Patch posted to http://gcc.gnu.org/ml/gcc-patches/2011-01/msg02118.html
Comment 3 Jan Kratochvil 2011-02-03 15:21:02 UTC
g++ (GCC) 4.6.0 20110203 (experimental) with the Comment 2 patch

template <typename T>
class F {
  typedef struct { int i; } C;
  C a;
};
F<int> f;

->

 <1><2d>: Abbrev Number: 2 (DW_TAG_class_type)
    <2e>   DW_AT_name        : (indirect string, offset: 0x37): F<int>  
 <2><39>: Abbrev Number: 3 (DW_TAG_structure_type)
    <3a>   DW_AT_name        : C        

and DW_TAG_typedef gets completely lost in such case.
Comment 4 Dodji Seketeli 2011-03-14 21:03:35 UTC
This is because G++ generates struct F<int>::C.  The instantiated
F<int>::C a typedef.  No anonymous struct is generated inside F<int>.
What is generated is really the same as for:

template<typename T>
class F
{
  struct C {int i};
  C a;
};
F<int> f;

I guess we could try hard to trick the dwarf emitter into describing
debug information for a typedef and an anonymous code that is actually
not generated (instantiated), but would that be really worth it?
Comment 5 Richard Biener 2011-03-15 16:24:27 UTC
(In reply to comment #4)
> This is because G++ generates struct F<int>::C.  The instantiated
> F<int>::C a typedef.  No anonymous struct is generated inside F<int>.
> What is generated is really the same as for:
> 
> template<typename T>
> class F
> {
>   struct C {int i};
>   C a;
> };
> F<int> f;
> 
> I guess we could try hard to trick the dwarf emitter into describing
> debug information for a typedef and an anonymous code that is actually
> not generated (instantiated), but would that be really worth it?

See also PR47939.  Yes, debug info consumers expect typedefs to be available
if they are used in source.
Comment 6 Dodji Seketeli 2011-03-16 10:14:42 UTC
> See also PR47939.  Yes, debug info consumers expect typedefs to be available
> if they are used in source.

I'll try again a little bit :-)

I think for templates the situation is a little bit different from
non-templates cases like PR47939.  Generally speaking we emit close to
no debug info for template *definitions*.  We emit debug info for
template instantiations.

As the instantiation doesn't contain the typedef (because
[dcl.typedef/8] says that the typedef actually names the anonymous
struct, so it is valid that the lookup of C yields a struct named C) I
find it acceptable to emit the debug info that is emitted now.

Now a possible way to go would be to change the output of the
instantiation; i.e make G++ generate the typedef and the anonymous type.
Just like what is done in the non-template case.  If this is agreed upon
by the C++ maintainers then I guess it could be a separate patch that
would go in after the one I am proposing at
http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00781.html
Comment 7 Dodji Seketeli 2011-03-16 21:05:03 UTC
Author: dodji
Date: Wed Mar 16 21:04:58 2011
New Revision: 171073

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=171073
Log:
PR debug/47510

gcc/

	PR debug/47510
	* dwarf2out.c (strip_naming_typedef): Factorize out of ...
	(lookup_type_die_strip_naming_typedef): ... here.
	(get_context_die): Use it.
	(gen_typedef_die): Add a DW_AT_{,MIPS_}linkage_name attribute to
	the anonymous struct named by the naming typedef.

gcc/testsuite/

        PR debug/47510
	* g++.dg/debug/dwarf2/typedef6.C: New test.

Added:
    trunk/gcc/testsuite/g++.dg/debug/dwarf2/typedef6.C
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/dwarf2out.c
    trunk/gcc/testsuite/ChangeLog
Comment 8 Dodji Seketeli 2011-03-16 21:11:19 UTC
Author: dodji
Date: Wed Mar 16 21:11:17 2011
New Revision: 171074

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=171074
Log:
PR debug/47510

gcc/

	PR debug/47510
	* dwarf2out.c (strip_naming_typedef): Factorize out of ...
	(lookup_type_die_strip_naming_typedef): ... here.
	(get_context_die): Use it.
	(gen_typedef_die): Add a DW_AT_{,MIPS_}linkage_name attribute to
	the anonymous struct named by the naming typedef.

gcc/testsuite/

	PR debug/47510
	* g++.dg/debug/dwarf2/typedef6.C: New test.

Added:
    branches/gcc-4_6-branch/gcc/testsuite/g++.dg/debug/dwarf2/typedef6.C
Modified:
    branches/gcc-4_6-branch/gcc/ChangeLog
    branches/gcc-4_6-branch/gcc/dwarf2out.c
    branches/gcc-4_6-branch/gcc/testsuite/ChangeLog
Comment 9 Dodji Seketeli 2011-03-16 21:30:27 UTC
The initial issue has been fixed in trunk (4.7) and 4.6 so far.  There
are two tangent issues that remain, though.  One is the template
related case raised by Jan in comment #3, and the other one is that
constructors of the anonymous struct are named t.  They should also be
anonymous and have DW_AT_linkage_name set to t.  This is from a
comment Jason made at
http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00926.html.  So I am
keeping this bug open to track these.  I will maybe open separate bugs
for these issues at some point.
Comment 10 Dodji Seketeli 2011-03-17 10:36:01 UTC
I have reverted the patch from 4.6 for now because I have apparently committed a bit too quickly.
Comment 11 Dodji Seketeli 2011-03-17 16:41:24 UTC
Author: dodji
Date: Thu Mar 17 16:41:05 2011
New Revision: 171105

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=171105
Log:
PR debug/47510

gcc/

	PR debug/47510
	* dwarf2out.c (strip_naming_typedef): Factorize out of ...
	(lookup_type_die_strip_naming_typedef): ... here.
	(get_context_die): Use it.
	(gen_typedef_die): Add a DW_AT_{,MIPS_}linkage_name attribute to
	the anonymous struct named by the naming typedef.

gcc/testsuite/

	PR debug/47510
	* g++.dg/debug/dwarf2/typedef6.C: New test.

Added:
    branches/gcc-4_6-branch/gcc/testsuite/g++.dg/debug/dwarf2/typedef6.C
Modified:
    branches/gcc-4_6-branch/gcc/ChangeLog
    branches/gcc-4_6-branch/gcc/dwarf2out.c
    branches/gcc-4_6-branch/gcc/testsuite/ChangeLog
Comment 12 Jakub Jelinek 2011-03-25 19:52:28 UTC
GCC 4.6.0 is being released, adjusting target milestone.
Comment 13 Dodji Seketeli 2011-04-14 08:14:01 UTC
Unassigning myself as the initial bug is fixed in 4.6.
Comment 14 Jan Kratochvil 2011-04-14 08:27:46 UTC
Comment 3 has been filed as new PR debug/48603.
Comment 15 dbeichl 2011-10-10 13:47:15 UTC
The same thing can happen for unions in c++11. Consider the following:

struct some_struct
{
  some_struct() = default;
  some_struct(int v) {}
};

typedef union {
    int x;
    some_struct y;
} a_union_t;

a_union_t z;

This creates a DW_TAG_typedef with children. I propose to extend the
candidate patch to unions:

--- gcc/dwarf2out.c 2011-09-15 12:16:36.000000000 +0200
+++ gcc/dwarf2out.c 2011-10-10 13:56:09.000000000 +0200
@@ -8106,7 +8106,7 @@
 strip_naming_typedef (tree type, dw_die_ref type_die)
 {
   if (type
-      && TREE_CODE (type) == RECORD_TYPE
+      && ( TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE )
       && type_die
       && type_die->die_tag == DW_TAG_typedef
       && is_naming_typedef_decl (TYPE_NAME (type)))
Comment 16 Václav Šmilauer 2012-03-04 18:30:15 UTC
(In reply to comment #15)
> The same thing can happen for unions in c++11.
I am being hit by this bug in c++11, though I am not able to follow the whole discussion. Can I get a concise summary on what kind of construct triggers the problem so that I can work it around in my code? Stucts with default ctors within unions? Thanks!

(Compiling gcc snapshot from 28/2/2012 now to see if it is still an issue).