public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug debug/95437] New: DW_TAG_typedef for template alias missing template type parameters
@ 2020-05-30 13:09 palves at redhat dot com
  2020-05-30 15:43 ` [Bug debug/95437] " palves at redhat dot com
  0 siblings, 1 reply; 2+ messages in thread
From: palves at redhat dot com @ 2020-05-30 13:09 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95437

            Bug ID: 95437
           Summary: DW_TAG_typedef for template alias missing template
                    type parameters
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: debug
          Assignee: unassigned at gcc dot gnu.org
          Reporter: palves at redhat dot com
  Target Milestone: ---

Currently GCC represents instantiations of alias templates using DW_TAG_typedef
instead of DW_TAG_template_alias.  

And, while Clang does the same (at least 5.0.2 does), Clang includes the
template parameters in the typedef name, while GCC leaves the template
parameters out.  This causes problems in GDB.

In more detail, with the following program:

~~~
template<typename T, typename U> struct Templ2 { static void method () {} };
template<typename T> using AliasTempl = Templ2<char, T>;
typedef unsigned int UInt;

AliasTempl<int> aliastmpl1;
AliasTempl<long> aliastmpl2;
AliasTempl<UInt> aliastmpl3;

int main () { return 0; }
~~~

If compiled with Clang (I have 5.0.2 handy), we get:

 <1><2a>: Abbrev Number: 2 (DW_TAG_variable)
    <2b>   DW_AT_name        : (indirect string, offset: 0xba): aliastmpl1
    <2f>   DW_AT_type        : <0x3f>
 <1><3f>: Abbrev Number: 3 (DW_TAG_typedef)
    <40>   DW_AT_type        : <0x4a>
    <44>   DW_AT_name        : (indirect string, offset: 0xe0): AliasTempl<int>
 <1><4a>: Abbrev Number: 4 (DW_TAG_structure_type)
    <4b>   DW_AT_name        : (indirect string, offset: 0xce): Templ2<char,
int>

 <1><73>: Abbrev Number: 2 (DW_TAG_variable)
    <74>   DW_AT_name        : (indirect string, offset: 0xf0): aliastmpl2
    <78>   DW_AT_type        : <0x88>
...
 <1><88>: Abbrev Number: 3 (DW_TAG_typedef)
    <89>   DW_AT_type        : <0x93>
    <8d>   DW_AT_name        : (indirect string, offset: 0x117):
AliasTempl<long>
 <1><93>: Abbrev Number: 4 (DW_TAG_structure_type)
    <94>   DW_AT_name        : (indirect string, offset: 0x104): Templ2<char,
long>

 <1><b5>: Abbrev Number: 2 (DW_TAG_variable)
    <b6>   DW_AT_name        : (indirect string, offset: 0x128): aliastmpl3
    <ba>   DW_AT_type        : <0xca>
(DW_OP_addr: 60101f)
 <1><ca>: Abbrev Number: 3 (DW_TAG_typedef)
    <cb>   DW_AT_type        : <0xd5>
    <cf>   DW_AT_name        : (indirect string, offset: 0x15b):
AliasTempl<UInt>
 <1><d5>: Abbrev Number: 4 (DW_TAG_structure_type)
    <d6>   DW_AT_name        : (indirect string, offset: 0x140): Templ2<char,
unsigned int>

So when debugging the Clang-built binary, we get:

(gdb) whatis aliastmpl1
type = AliasTempl<int>
(gdb) whatis aliastmpl2
type = AliasTempl<long>
(gdb) whatis aliastmpl3
type = AliasTempl<UInt>
(gdb) ptype aliastmpl1
type = struct Templ2<char, int> [with T = char, U = int] {
    <no data fields>
}
(gdb) ptype aliastmpl2
type = struct Templ2<char, long> [with T = char, U = long] {
    <no data fields>
}
(gdb) ptype aliastmpl3
type = struct Templ2<char, unsigned int> [with T = char, U = unsigned int] {
    <no data fields>
}
(gdb) 

However, with GCC-built binaries we get three different typedefs with the same
name:

 <1><34>: Abbrev Number: 3 (DW_TAG_structure_type)
    <35>   DW_AT_name        : (indirect string, offset: 0x10a): Templ2<char,
int>
 <1><50>: Abbrev Number: 5 (DW_TAG_typedef)
    <51>   DW_AT_name        : (indirect string, offset: 0x23): AliasTempl
    <58>   DW_AT_type        : <0x34>
 <1><5c>: Abbrev Number: 6 (DW_TAG_variable)
    <5d>   DW_AT_name        : (indirect string, offset: 0x17b): aliastmpl1
    <64>   DW_AT_type        : <0x50>

<1><72>: Abbrev Number: 3 (DW_TAG_structure_type)
    <73>   DW_AT_name        : (indirect string, offset: 0x11c): Templ2<char,
long int>
 <1><8e>: Abbrev Number: 5 (DW_TAG_typedef)
    <8f>   DW_AT_name        : (indirect string, offset: 0x23): AliasTempl
    <96>   DW_AT_type        : <0x72>
 <1><9a>: Abbrev Number: 6 (DW_TAG_variable)
    <9b>   DW_AT_name        : (indirect string, offset: 0x0): aliastmpl2
    <a2>   DW_AT_type        : <0x8e>

<1><b0>: Abbrev Number: 3 (DW_TAG_structure_type)
    <b1>   DW_AT_name        : (indirect string, offset: 0xef): Templ2<char,
unsigned int>
 <1><cc>: Abbrev Number: 5 (DW_TAG_typedef)
    <cd>   DW_AT_name        : (indirect string, offset: 0x23): AliasTempl
    <d4>   DW_AT_type        : <0xb0>
 <1><d8>: Abbrev Number: 6 (DW_TAG_variable)
    <d9>   DW_AT_name        : (indirect string, offset: 0x18): aliastmpl3
    <e0>   DW_AT_type        : <0xcc>

I.e., all three typedefs are named "AliasTempl".

This results in this with GDB:

(gdb) whatis aliastmpl1
type = AliasTempl
(gdb) whatis aliastmpl2
type = AliasTempl
(gdb) whatis aliastmpl3
type = AliasTempl
(gdb) ptype aliastmpl1
type = struct Templ2<char, int> [with T = char, U = int] {
    <no data fields>
}
(gdb) ptype aliastmpl2
type = struct Templ2<char, long> [with T = char, U = long] {
    <no data fields>
}
(gdb) ptype aliastmpl3
type = struct Templ2<char, unsigned int> [with T = char, U = unsigned int] {
    <no data fields>
}

I.e., the "whatis" command shows the same name three times, even though these
are different types.

And of course, the user is able to query info about the bogus "AliasTempl"
typedef:

(gdb) whatis AliasTempl
type = Templ2<char, int>


This "missing template parameters info" issue also prevents setting breakpoints
using the alias template with GCC-built binaries.  I.e., while this works (in
current GDB master) with Clang-built binaries:

(gdb) b AliasTempl<int>::method()
Breakpoint 2 at 0x4004c4: file alias-template.cc, line 20.
(gdb) info breakpoints 
Num     Type           Disp Enb Address            What
2       breakpoint     keep y   0x00000000004004c4 in Templ2<char,
int>::method() at alias-template.cc:20

It does not work with GCC-built binaries:

(gdb) b AliasTempl<int>::method()
Function "AliasTempl<int>::method()" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n


The above was tested with gcc 7.3.1, gcc 10 and clang 5.0.2.

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [Bug debug/95437] DW_TAG_typedef for template alias missing template type parameters
  2020-05-30 13:09 [Bug debug/95437] New: DW_TAG_typedef for template alias missing template type parameters palves at redhat dot com
@ 2020-05-30 15:43 ` palves at redhat dot com
  0 siblings, 0 replies; 2+ messages in thread
From: palves at redhat dot com @ 2020-05-30 15:43 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95437

--- Comment #1 from Pedro Alves <palves at redhat dot com> ---
> This "missing template parameters info" issue also prevents setting breakpoints > using the alias template with GCC-built binaries.

This GDB commit adds a testcase exercising this issue:

  https://sourceware.org/pipermail/gdb-patches/2020-May/169163.html

It's in the gdb.linespec/cp-replace-typedefs-ns-template.exp testcase which can
be run like this:

 $ make check TESTS="gdb.linespec/cp-replace-typedefs-ns-template.exp"

It currently passes cleanly with Clang, and with two XFAILs with GCC.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-05-30 15:43 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-30 13:09 [Bug debug/95437] New: DW_TAG_typedef for template alias missing template type parameters palves at redhat dot com
2020-05-30 15:43 ` [Bug debug/95437] " palves at redhat dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).