Hi! On the following testcase, in gdb ptype S<long>::m1 prints long as return type, but all the other methods show void instead. PR53756 added code to add_type_attribute if the return type is auto/decltype(auto), but we actually should look through references, pointers and qualifiers. Haven't included there DW_TAG_atomic_type, because I think at least ATM one can't use that in C++. Not sure about DW_TAG_array_type or what else could be deduced.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2020-04-04 Domani Hannes <ssb...@yahoo.de> Jakub Jelinek <ja...@redhat.com> PR debug/94459 * dwarf2out.c (gen_subprogram_die): Look through references, pointers and qualifiers when checking if in-class DIE had an 'auto' or 'decltype(auto)' return type to emit type again on definition. * g++.dg/debug/pr94459.C: New test. --- gcc/dwarf2out.c.jj 2020-04-03 10:04:44.704972108 +0200 +++ gcc/dwarf2out.c 2020-04-03 17:52:48.909483818 +0200 @@ -22905,11 +22905,19 @@ gen_subprogram_die (tree decl, dw_die_re != (unsigned) s.column)) add_AT_unsigned (subr_die, DW_AT_decl_column, s.column); - /* If the prototype had an 'auto' or 'decltype(auto)' return type, + /* If the prototype had a cv 'auto' or 'decltype(auto)' return type, emit the real type on the definition die. */ if (is_cxx () && debug_info_level > DINFO_LEVEL_TERSE) { dw_die_ref die = get_AT_ref (old_die, DW_AT_type); + while (die + && (die->die_tag == DW_TAG_reference_type + || die->die_tag == DW_TAG_rvalue_reference_type + || die->die_tag == DW_TAG_pointer_type + || die->die_tag == DW_TAG_const_type + || die->die_tag == DW_TAG_volatile_type + || die->die_tag == DW_TAG_restrict_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); --- gcc/testsuite/g++.dg/debug/pr94459.C.jj 2020-04-03 18:06:28.234725520 +0200 +++ gcc/testsuite/g++.dg/debug/pr94459.C 2020-04-03 18:05:59.287104932 +0200 @@ -0,0 +1,49 @@ +// PR debug/94459 +// { dg-do compile { target c++11 } } +// { dg-options "-g -dA" } + +template <typename T> +struct S +{ + T v; + S () : v (0) {} + auto m1 () { return v; } + auto &m2 () { return v; } + auto &&m3 () { return (T&&)v; } + const auto m4 () { return v; } + const auto &m5 () { return v; } + const auto &&m6 () { return (T&&)v; } + volatile auto m7 () { return v; } + volatile auto &m8 () { return v; } + volatile auto &&m9 () { return (T&&)v; } + volatile const auto m10 () { return v; } + volatile const auto &m11 () { return v; } + volatile const auto &&m12 () { return (T&&)v; } + const volatile auto m13 () { return v; } + const volatile auto &m14 () { return v; } + const volatile auto &&m15 () { return (T&&)v; } +#ifndef __STRICT_ANSI__ + __restrict const volatile auto &&m16 () { return (T&&)v; } + const __restrict auto &m17 () { return v; } +#endif +}; + +S<long> s, u, v; + +long +foo () +{ + return s.m1 () + s.m2 () + s.m3 () + s.m4 () + s.m5 () + + s.m6 () + s.m7 () + s.m8 () + s.m9 () + s.m10 () + + s.m11 () + s.m12 () + s.m13 () + s.m14 () + s.m15 () +#ifndef __STRICT_ANSI__ + + u.m16 () + v.m17 () +#endif + + 0; +} + +int +main () +{ + return foo (); +} Jakub