[Converted from Gnats 1113] ptype claims that destructors take an int arg. Release: GNU gdb 2003-03-03-cvs Environment: i686-pc-linux-gnu (Red Hat 7.3) GCC 3.1 DWARF 2 How-To-Repeat: Compile this: class C { public: ~C() {} }; int main() { C c; } Then: jackfruit$ /extra/gdb/mirror/src/gdb/gdb a.out GNU gdb 2003-03-03-cvs Copyright 2003 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i686-pc-linux-gnu"... (gdb) b main Breakpoint 1 at 0x8048500: file foo.cc, line 8. (gdb) r Starting program: /home/carlton/tmp/a.out Breakpoint 1, main () at foo.cc:8 8 C c; (gdb) ptype C type = class C { public: ~C(int); }
From: carlton@sources.redhat.com To: gdb-gnats@sourceware.org Cc: Subject: c++/1113 Date: 4 Mar 2003 17:02:21 -0000 CVSROOT: /cvs/src Module name: src Changes by: carlton@sourceware.org 2003-03-04 17:02:20 Modified files: gdb/testsuite : ChangeLog gdb/testsuite/gdb.c++: templates.exp Log message: 2003-03-04 David Carlton <carlton@math.stanford.edu> * gdb.c++/templates.exp (do_tests): Accept valid const in "print Garply<Garply<char> >:: garply". (test_ptype_of_templates): KFAIL "ptype T5<int>" and "ptype t5i" with respect to PR c++/1111; note also PR c++/1113. (test_template_breakpoints): KFAIL "constructor breakpoint" with respect to PR c++/1062. KFAIL "destructor breakpoint" with respect to PR c++/1112. Patches: http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/gdb/testsuite/ChangeLog.diff?cvsroot=src&r1=1.503&r2=1.504 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/gdb/testsuite/gdb.c++/templates.exp.diff?cvsroot=src&r1=1.17&r2=1.18
This looks like a GCC bug, not a GDB bug. Using llvm-dwarfdump, GCC's dwarf for the dtor looks like this: 0x00000051: DW_TAG_subprogram [5] * 0x00000052: DW_AT_external [DW_FORM_flag] (0x01) 0x00000053: DW_AT_name [DW_FORM_string] ("~C") 0x00000056: DW_AT_decl_file [DW_FORM_data1] (0x01) 0x00000057: DW_AT_decl_line [DW_FORM_data1] (0x03) 0x00000058: DW_AT_declaration [DW_FORM_flag] (0x01) 0x00000059: DW_AT_object_pointer [DW_FORM_ref4] (cu + 0x005d => {0x0000005d}) 0x0000005d: DW_TAG_formal_parameter [4] 0x0000005e: DW_AT_type [DW_FORM_ref4] (cu + 0x006b => {0x0000006b}) 0x00000062: DW_AT_artificial [DW_FORM_flag] (0x01) 0x00000063: DW_TAG_formal_parameter [4] 0x00000064: DW_AT_type [DW_FORM_ref4] (cu + 0x0071 => {0x00000071}) 0x00000068: DW_AT_artificial [DW_FORM_flag] (0x01) 0x00000069: NULL 0x0000006a: NULL whereas Clang's dwarf looks like this: 0x00000086: DW_TAG_subprogram [10] * 0x00000087: DW_AT_accessibility [DW_FORM_data1] (0x01) 0x00000088: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000049] = "~C") 0x0000008c: DW_AT_decl_file [DW_FORM_data1] (0x01) 0x0000008d: DW_AT_decl_line [DW_FORM_data1] (0x03) 0x0000008e: DW_AT_declaration [DW_FORM_flag_present] (true) 0x0000008e: DW_AT_external [DW_FORM_flag_present] (true) 0x0000008e: DW_TAG_formal_parameter [9] 0x0000008f: DW_AT_type [DW_FORM_ref4] (cu + 0x006b => {0x0000006b}) 0x00000093: DW_AT_artificial [DW_FORM_flag_present] (true) 0x00000093: NULL 0x00000094: NULL And GDB's output when given your example and compiled with Clang is: (well I modified the example a bit: struct C { C() {} ~C() {} }; int main() { C c; } (mostly I was curious whether "(void)" was the way GDB was printing things generally or whether it would print the ctor as "()" instead)): ptype C type = struct C { public: C(void); ~C(void); } Shall we close this & open a GCC bug instead? (& change the kfail to an xfail referencing the GCC bug - and add the correct pattern so Clang can pass this test)
(In reply to comment #2) > 0x00000063: DW_TAG_formal_parameter [4] > 0x00000064: DW_AT_type [DW_FORM_ref4] (cu + 0x0071 => {0x00000071}) > 0x00000068: DW_AT_artificial [DW_FORM_flag] (0x01) > Shall we close this & open a GCC bug instead? (& change the kfail to an xfail > referencing the GCC bug - and add the correct pattern so Clang can pass this > test) Arguably it is still a gdb bug since the parameter is marked artificial. I think that gdb may be making an explicit choice here, though, since c_type_print_args explicitly prints artificial arguments. There is a GCC bug in this area: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37237 It may not seem related but if you read the comments, the gist is that GCC is just emitting DWARF for one of the constructors, whereas it should probably emit DWARF for all of them. Adding a pattern for clang to pass seems fine to me.
(In reply to Tom Tromey from comment #3) > Arguably it is still a gdb bug since the parameter is marked artificial. > I think that gdb may be making an explicit choice here, though, since > c_type_print_args explicitly prints artificial arguments. Yeah, this just bit me, too, while trying to write some tests using cp_test_ptype_class. It kept failing on the dtor, "~foo(int)". The problem here is that cp_type_print_method_args doesn't ignore artificial arguments, except possibly the first one if the method isn't static. [That seems equally dubious to me, too. Compilers don't *have* to implement methods using artificial `this'. :-)] In any case, I'm working up a patch. To see ~foo(int) in 2017 is just plain disheartening! I don't think this should harm Clang in any way, but if there is test suite massaging needed, I don't think there would be a problem with that.
The master branch has been updated by Keith Seitz <kseitz@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=5f4d10850850cd95af5e95a16848c8c07a273d88 commit 5f4d10850850cd95af5e95a16848c8c07a273d88 Author: Keith Seitz <keiths@redhat.com> Date: Fri Mar 10 10:32:09 2017 -0800 c++/8218: Destructors w/arguments. For a long time now, c++/8218 has noted that GDB is printing argument types for destructors: (gdb) ptype A type = class A { public: ~A(int); } This happens because cp_type_print_method_args doesn't ignore artificial arguments. [It ignores the first `this' pointer because it simply skips the first argument for any non-static function.] This patch fixes this: (gdb) ptype A type = class A { public: ~A(); } I've adjusted gdb.cp/templates.exp to account for this and added a new passing regexp. gdb/ChangeLog PR c++/8218 * c-typeprint.c (cp_type_print_method_args): Skip artificial arguments. gdb/testsuite/ChangeLog PR c++/8128 * gdb.cp/templates.exp (test_ptype_of_templates): Remove argument type from destructor regexps. Add a branch which actually passes the test. Adjust "ptype t5i" test names.
Bug 8128 has been closed, but commit 5f4d10850850cd95af5e95a16848c8c07a273d88 apparently fixes this one.
(In reply to Sourceware Commits from comment #5) > The master branch has been updated by Keith Seitz <kseitz@sourceware.org>: > > https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git; > h=5f4d10850850cd95af5e95a16848c8c07a273d88 > > commit 5f4d10850850cd95af5e95a16848c8c07a273d88 > Author: Keith Seitz <keiths@redhat.com> > Date: Fri Mar 10 10:32:09 2017 -0800 > > c++/8218: Destructors w/arguments. > > For a long time now, c++/8218 has noted that GDB is printing argument > types > for destructors: > > (gdb) ptype A > type = class A { > public: > ~A(int); > } > > This happens because cp_type_print_method_args doesn't ignore artificial > arguments. [It ignores the first `this' pointer because it simply skips > the first argument for any non-static function.] > > This patch fixes this: > > (gdb) ptype A > type = class A { > public: > ~A(); > } > > I've adjusted gdb.cp/templates.exp to account for this and added a new > passing regexp. > > gdb/ChangeLog > > PR c++/8218 > * c-typeprint.c (cp_type_print_method_args): Skip artificial arguments. Fixed.