public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "palves at redhat dot com" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug debug/95437] New: DW_TAG_typedef for template alias missing template type parameters
Date: Sat, 30 May 2020 13:09:54 +0000	[thread overview]
Message-ID: <bug-95437-4@http.gcc.gnu.org/bugzilla/> (raw)

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.

             reply	other threads:[~2020-05-30 13:09 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-30 13:09 palves at redhat dot com [this message]
2020-05-30 15:43 ` [Bug debug/95437] " palves at redhat dot com

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-95437-4@http.gcc.gnu.org/bugzilla/ \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=gcc-bugs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).