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

            Bug ID: 94459
           Summary: Missing c++ debug information for 'auto&' return type
           Product: gcc
           Version: 9.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: debug
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ssbssa at yahoo dot de
  Target Milestone: ---

For the following example:

template <typename T>
struct MyClass
{
  T value;
  auto get()
  {
    return value;
  }
  auto &get_ref()
  {
    return value;
  }
  auto &&get_r_ref()
  {
    return (T&&)value;
  }
  const auto c_get()
  {
    return value;
  }
  const auto &c_get_ref()
  {
    return value;
  }
  const auto &&c_get_r_ref()
  {
    return (T&&)value;
  }
};

int main()
{
  MyClass<int> mc{1};
  return (mc.get() + mc.get_ref() + mc.get_r_ref()
      + mc.c_get() + mc.c_get_ref() + mc.c_get_r_ref());
}

For the simple 'auto' case, the debugger knows the real return type:

(gdb) pt MyClass<int>::get
type = int (MyClass<int> * const)

But not for the others:

(gdb) pt MyClass<int>::get_ref
type = void &(MyClass<int> * const)
(gdb) pt MyClass<int>::get_r_ref
type = void &&(MyClass<int> * const)
(gdb) pt MyClass<int>::c_get
type = void (MyClass<int> * const)
(gdb) pt MyClass<int>::c_get_ref
type = void &(MyClass<int> * const)
(gdb) pt MyClass<int>::c_get_r_ref
type = void &&(MyClass<int> * const)

For 'auto', extra type information is stored on the definition die, this was
implemented here:
https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=2e5e7103a39315664f9a625bea42981f5251c27e


So I came up with the following patch:

--- gcc/dwarf2out.c     2020-03-12 12:07:21.000000000 +0100
+++ gcc/dwarf2out.c     2020-04-02 14:54:03.680451100 +0200
@@ -23016,6 +23016,11 @@
          if (is_cxx () && debug_info_level > DINFO_LEVEL_TERSE)
            {
              dw_die_ref die = get_AT_ref (old_die, DW_AT_type);
+             if (die->die_tag == DW_TAG_reference_type
+                 || die->die_tag == DW_TAG_rvalue_reference_type)
+               die = get_AT_ref (die, DW_AT_type);
+             if (die->die_tag == DW_TAG_const_type)
+               die = get_AT_ref (die, DW_AT_type);
              if (die == auto_die || die == decltype_auto_die)
                add_type_attribute (subr_die, TREE_TYPE (TREE_TYPE (decl)),
                                    TYPE_UNQUALIFIED, false, context_die);

This seems to work fine:

(gdb) pt MyClass<int>::get
type = int (MyClass<int> * const)
(gdb) pt MyClass<int>::get_ref
type = int &(MyClass<int> * const)
(gdb) pt MyClass<int>::get_r_ref
type = int &&(MyClass<int> * const)
(gdb) pt MyClass<int>::c_get
type = const int (MyClass<int> * const)
(gdb) pt MyClass<int>::c_get_ref
type = const int &(MyClass<int> * const)
(gdb) pt MyClass<int>::c_get_r_ref
type = const int &&(MyClass<int> * const)

But I can't run the testsuite (I'm on Windows), so I can't be sure that this
would break anything else.

Reply via email to