Message ID | 52E7E353.3020604@redhat.com |
---|---|
State | New |
Headers | show |
On 01/28/2014 06:05 PM, Jason Merrill wrote: > My earlier work to support return type deduction omitted support for > debugging information; this patch fixes that oversight. It also > corrects the mangled name of 'operator auto', which should reflect the > 'auto' rather than the deduced return type. > > Tested x86_64-pc-linux-gnu, applying to trunk. Ah! Then I guess that in order to fix c++/58561 only is_base_type needs tweaking: shall we change the default to just return 0? Thanks, Paolo.
On 01/28/2014 01:33 PM, Paolo Carlini wrote: > Ah! Then I guess that in order to fix c++/58561 only is_base_type needs > tweaking: shall we change the default to just return 0? Makes sense. Jason
Jason Merrill <jason@redhat.com> writes:
> +// { dg-final { scan-assembler "a1.*(0x\[0-9a-f\]+)\[ \t\]*# DW_AT_type.*\\1. DW_TAG_unspecified_type.*DW_AT_specification\[\n\r\]{1,2}\[^\n\r\]*(0x\[0-9a-f\]+)\[ \t\]*# DW_AT_type.*\\2. DW_TAG_base_type" } }
This regexp is completely broken.
Here's what I get on m68k:
.uleb128 0x3 | (DIE (0x2b) DW_TAG_subprogram)
| DW_AT_external
.ascii "a1\0" | DW_AT_name
.byte 0x1 | DW_AT_decl_file (/daten/aranym/gcc/gcc-20140129/gcc/testsuite/g++.dg/debug/dwarf2/auto1.C)
.byte 0x17 | DW_AT_decl_line
.long .LASF2 | DW_AT_linkage_name: "_ZN1A2a1Ev"
.long 0x44 | DW_AT_type
| DW_AT_declaration
.long 0x3d | DW_AT_object_pointer
.uleb128 0x4 | (DIE (0x3d) DW_TAG_formal_parameter)
.long 0x49 | DW_AT_type
| DW_AT_artificial
.byte 0 | end of children of DIE 0x2b
.byte 0 | end of children of DIE 0x21
.uleb128 0x5 | (DIE (0x44) DW_TAG_unspecified_type)
.long .LASF3 | DW_AT_name: "auto"
.uleb128 0x6 | (DIE (0x49) DW_TAG_pointer_type)
.byte 0x4 | DW_AT_byte_size
.long 0x21 | DW_AT_type
.uleb128 0x7 | (DIE (0x4f) DW_TAG_subprogram)
.long 0x2b | DW_AT_specification
.long 0x77 | DW_AT_type
.long .LFB0 | DW_AT_low_pc
.long .LFE0-.LFB0 | DW_AT_high_pc
.uleb128 0x1 | DW_AT_frame_base
.byte 0x9c | DW_OP_call_frame_cfa
.long 0x6a | DW_AT_object_pointer
| DW_AT_GNU_all_call_sites
.long 0x77 | DW_AT_sibling
.uleb128 0x8 | (DIE (0x6a) DW_TAG_formal_parameter)
.long .LASF4 | DW_AT_name: "this"
.long 0x7e | DW_AT_type
| DW_AT_artificial
.uleb128 0x2 | DW_AT_location
.byte 0x91 | DW_OP_fbreg
.sleb128 0
.byte 0 | end of children of DIE 0x4f
.uleb128 0x9 | (DIE (0x77) DW_TAG_base_type)
.byte 0x4 | DW_AT_byte_size
.byte 0x5 | DW_AT_encoding
.ascii "int\0" | DW_AT_name
And this is what I get on ia64:
.uleb128 0x3 // (DIE (0x2f) DW_TAG_subprogram)
// DW_AT_external
.ascii "a1\0" // DW_AT_name
data1 0x1 // DW_AT_decl_file (/usr/local/gcc/gcc-20140129/gcc/testsuite/g++.dg/debug/dwarf2/auto1.C)
data1 0x17 // DW_AT_decl_line
data4.ua @secrel(.LASF2) // DW_AT_linkage_name: "_ZN1A2a1Ev"
data4.ua 0x48 // DW_AT_type
// DW_AT_declaration
data4.ua 0x41 // DW_AT_object_pointer
.uleb128 0x4 // (DIE (0x41) DW_TAG_formal_parameter)
data4.ua 0x4d // DW_AT_type
// DW_AT_artificial
data1 0 // end of children of DIE 0x2f
data1 0 // end of children of DIE 0x25
.uleb128 0x5 // (DIE (0x48) DW_TAG_unspecified_type)
data4.ua @secrel(.LASF3) // DW_AT_name: "auto"
.uleb128 0x6 // (DIE (0x4d) DW_TAG_pointer_type)
data1 0x8 // DW_AT_byte_size
data4.ua 0x25 // DW_AT_type
.uleb128 0x7 // (DIE (0x53) DW_TAG_subprogram)
data4.ua 0x2f // DW_AT_specification
data4.ua 0x85 // DW_AT_type
data8.ua .LFB0 // DW_AT_low_pc
data8.ua .LFE0-.LFB0 // DW_AT_high_pc
data4.ua @secrel(.LLST0) // DW_AT_frame_base
data4.ua 0x78 // DW_AT_object_pointer
// DW_AT_GNU_all_call_sites
data4.ua 0x85 // DW_AT_sibling
.uleb128 0x8 // (DIE (0x78) DW_TAG_formal_parameter)
data4.ua @secrel(.LASF4) // DW_AT_name: "this"
data4.ua 0x8c // DW_AT_type
// DW_AT_artificial
.uleb128 0x2 // DW_AT_location
data1 0x91 // DW_OP_fbreg
.sleb128 0
data1 0 // end of children of DIE 0x53
.uleb128 0x9 // (DIE (0x85) DW_TAG_base_type)
data1 0x4 // DW_AT_byte_size
data1 0x5 // DW_AT_encoding
.ascii "int\0" // DW_AT_name
Andreas.
On 01/29/2014 05:37 AM, Andreas Schwab wrote: > Jason Merrill <jason@redhat.com> writes: > >> +// { dg-final { scan-assembler "a1.*(0x\[0-9a-f\]+)\[ \t\]*# DW_AT_type.*\\1. DW_TAG_unspecified_type.*DW_AT_specification\[\n\r\]{1,2}\[^\n\r\]*(0x\[0-9a-f\]+)\[ \t\]*# DW_AT_type.*\\2. DW_TAG_base_type" } } > > This regexp is completely broken. I'll fix it shortly. Jason
commit 2b1d597e10480dfc2aefe251990cacc2af11d7cc Author: Jason Merrill <jason@redhat.com> Date: Wed Nov 6 12:02:55 2013 -0500 PR c++/53756 gcc/ * dwarf2out.c (auto_die): New static. (gen_type_die_with_usage): Handle C++1y 'auto'. (gen_subprogram_die): If in-class DIE had 'auto', emit type again on definition. gcc/cp/ * mangle.c (write_unqualified_name): Handle operator auto. diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index be3c698..add73cf 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -1231,6 +1231,9 @@ write_unqualified_name (const tree decl) fn_type = get_mostly_instantiated_function_type (decl); type = TREE_TYPE (fn_type); } + else if (FNDECL_USED_AUTO (decl)) + type = (DECL_STRUCT_FUNCTION (decl)->language + ->x_auto_return_pattern); else type = DECL_CONV_FN_TYPE (decl); write_conversion_operator_name (type); diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 22282d8..f6efd1f 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -247,6 +247,9 @@ static GTY(()) bool cold_text_section_used = false; /* The default cold text section. */ static GTY(()) section *cold_text_section; +/* The DIE for C++1y 'auto' in a function return type. */ +static GTY(()) dw_die_ref auto_die; + /* Forward declarations for functions defined in this file. */ static char *stripattributes (const char *); @@ -17999,6 +18002,13 @@ gen_subprogram_die (tree decl, dw_die_ref context_die) add_AT_file (subr_die, DW_AT_decl_file, file_index); if (get_AT_unsigned (old_die, DW_AT_decl_line) != (unsigned) s.line) add_AT_unsigned (subr_die, DW_AT_decl_line, s.line); + + /* If the prototype had an 'auto' return type, emit the real + type on the definition die. */ + if (is_cxx() && debug_info_level > DINFO_LEVEL_TERSE + && get_AT_ref (old_die, DW_AT_type) == auto_die) + add_type_attribute (subr_die, TREE_TYPE (TREE_TYPE (decl)), + 0, 0, context_die); } } else @@ -19820,6 +19830,25 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die, break; default: + // A C++ function with deduced return type can have + // a TEMPLATE_TYPE_PARM named 'auto' in its type. + if (is_cxx ()) + { + tree name = TYPE_NAME (type); + if (TREE_CODE (name) == TYPE_DECL) + name = DECL_NAME (name); + if (name == get_identifier ("auto")) + { + if (!auto_die) + { + auto_die = new_die (DW_TAG_unspecified_type, + comp_unit_die (), NULL_TREE); + add_name_attribute (auto_die, "auto"); + } + equate_type_number_to_die (type, auto_die); + break; + } + } gcc_unreachable (); } diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn12.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn12.C index e4e58e8..ab4a1bb 100644 --- a/gcc/testsuite/g++.dg/cpp1y/auto-fn12.C +++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn12.C @@ -1,5 +1,5 @@ // { dg-options -std=c++1y } -// { dg-final { scan-assembler "_ZN1AIiEcviEv" } } +// { dg-final { scan-assembler "_ZN1AIiEcvDaEv" } } template <class T> struct A { diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn22.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn22.C new file mode 100644 index 0000000..f05cbb9 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn22.C @@ -0,0 +1,9 @@ +// { dg-options "-std=c++1y" } + +struct A +{ + operator auto(); +}; + +// { dg-final { scan-assembler "_ZN1AcvDaEv" } } +A::operator auto() { return 42; } diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/auto1.C b/gcc/testsuite/g++.dg/debug/dwarf2/auto1.C new file mode 100644 index 0000000..188ca11 --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/dwarf2/auto1.C @@ -0,0 +1,30 @@ +// PR c++/53756 +// { dg-options "-std=c++1y -g -dA -fno-debug-types-section" } +// We're looking for something like + +// .uleb128 0x3 # (DIE (0x33) DW_TAG_subprogram) +// .ascii "a1\0" # DW_AT_name +// .long 0x4c # DW_AT_type +//... +// .uleb128 0x5 # (DIE (0x4c) DW_TAG_unspecified_type) +// .long .LASF6 # DW_AT_name: "auto" +//... +// .uleb128 0x7 # (DIE (0x57) DW_TAG_subprogram) +// .long 0x33 # DW_AT_specification +// .long 0x87 # DW_AT_type +//... +// .uleb128 0x9 # (DIE (0x87) DW_TAG_base_type) +// .ascii "int\0" # DW_AT_name + +// { dg-final { scan-assembler "a1.*(0x\[0-9a-f\]+)\[ \t\]*# DW_AT_type.*\\1. DW_TAG_unspecified_type.*DW_AT_specification\[\n\r\]{1,2}\[^\n\r\]*(0x\[0-9a-f\]+)\[ \t\]*# DW_AT_type.*\\2. DW_TAG_base_type" } } + +struct A +{ + auto a1 () { return 42; } +}; + +int main() +{ + A a; + a.a1(); +}