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.