From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11049 invoked by alias); 12 Oct 2013 15:28:43 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 11040 invoked by uid 89); 12 Oct 2013 15:28:43 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-4.3 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD,SPF_HELO_PASS,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 12 Oct 2013 15:28:41 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r9CFSeHX022380 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Sat, 12 Oct 2013 11:28:40 -0400 Received: from host2.jankratochvil.net (ovpn-116-94.ams2.redhat.com [10.36.116.94]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r9CFSawW020148 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NO) for ; Sat, 12 Oct 2013 11:28:38 -0400 Date: Sat, 12 Oct 2013 15:28:00 -0000 From: Jan Kratochvil To: gdb-patches@sourceware.org Subject: [patch] Support C++11 rvalue (move constructor) Message-ID: <20131012152836.GA9438@host2.jankratochvil.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes X-SW-Source: 2013-10/txt/msg00403.txt.bz2 Hi, currently one cannot debug C++11 move constructors, one gets: # in C::C (C &&o) (gdb) print o $1 = This fix is easy but it handles && rvalue reference like & lvalue reference. Therefore there is a KFAIL in the testcase for it. I do not think GDB needs to handle && differently - except for displaying && instead of &. Implementing proper && into inferior type system means: (1) Either add TYPE_CODE_RVALUE_REF besides TYPE_CODE_REF which is pretty tedious - TYPE_CODE_REF is referenced in 155 GDB LoCs - due to missing types virtualization. In almost all cases one will do: - if (TYPE_CODE (t) == TYPE_CODE_REF) + if (TYPE_CODE (t) == TYPE_CODE_REF + || TYPE_CODE (t) == TYPE_CODE_RVALUE_REF) or to add new main_type::flag_ref_is_rvalue valid only for TYPE_CODE_REF but that is sure not a clean implementation. (2) One would need to add type.rvalue_reference_type (besides type.reference_type) to prevent leaks of types. This would mean increasing the current sizeof (struct type) 40 -> 48. The proper solution is to rather implement reference counting or garbage collecting of types and merge struct type into struct main_type. Anyway currently I find the patch below as a good enough hack as currently I find it a bit blocker when using C++11. Thanks, Jan gdb/ 2013-10-12 Jan Kratochvil PR c++/16043 * c-exp.y (ptr_operator): Handle also ANDAND as tp_reference. * dwarf2read.c (process_die): Skip also DW_TAG_rvalue_reference_type. (read_type_die_1): Handle also DW_TAG_rvalue_reference_type. * gdbtypes.h (enum type_code): Extend comment for TYPE_CODE_REF. (struct type): Extend comment for reference_type. gdb/testsuite/ 2013-10-12 Jan Kratochvil * gdb.cp/rvalue.cc: New file. * gdb.cp/rvalue.exp: New file. diff --git a/gdb/c-exp.y b/gdb/c-exp.y index 77713dd..653a5ad 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -1115,6 +1115,10 @@ ptr_operator: { insert_type (tp_reference); } | '&' ptr_operator { insert_type (tp_reference); } + | ANDAND + { insert_type (tp_reference); } + | ANDAND ptr_operator + { insert_type (tp_reference); } ; ptr_operator_ts: ptr_operator diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index aa109e0..47b1cb5 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -7990,6 +7990,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu) case DW_TAG_pointer_type: case DW_TAG_ptr_to_member_type: case DW_TAG_reference_type: + case DW_TAG_rvalue_reference_type: case DW_TAG_string_type: break; @@ -18010,6 +18011,7 @@ read_type_die_1 (struct die_info *die, struct dwarf2_cu *cu) this_type = read_tag_ptr_to_member_type (die, cu); break; case DW_TAG_reference_type: + case DW_TAG_rvalue_reference_type: this_type = read_tag_reference_type (die, cu); break; case DW_TAG_const_type: diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index 5e8d1e7..d5e2b7a 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -129,7 +129,8 @@ enum type_code by the Itanium C++ ABI (used by GCC on all platforms). */ TYPE_CODE_MEMBERPTR, - TYPE_CODE_REF, /* C++ Reference types */ + TYPE_CODE_REF, /* C++ Reference types + (both lvalue & and rvalue &&) */ TYPE_CODE_CHAR, /* *real* character type */ @@ -657,7 +658,7 @@ struct type struct type *pointer_type; - /* C++: also need a reference type. */ + /* C++: also need a reference type (both for lvalue & and rvalue &&). */ struct type *reference_type; diff --git a/gdb/testsuite/gdb.cp/rvalue.cc b/gdb/testsuite/gdb.cp/rvalue.cc new file mode 100644 index 0000000..7a78b97 --- /dev/null +++ b/gdb/testsuite/gdb.cp/rvalue.cc @@ -0,0 +1,38 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2013 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +class C +{ +public: + C () {} + C (C &&o); + int i = 42; +}; + +C::C (C &&o) +{ + i = o.i; /* o-is-ready */ +} + +int +main() +{ + C a; + C b (std::move (a)); /* a-is-ready */ +} diff --git a/gdb/testsuite/gdb.cp/rvalue.exp b/gdb/testsuite/gdb.cp/rvalue.exp new file mode 100644 index 0000000..df3536b --- /dev/null +++ b/gdb/testsuite/gdb.cp/rvalue.exp @@ -0,0 +1,53 @@ +# Copyright 2013 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +if { [skip_cplus_tests] } { continue } + +standard_testfile .cc + +if {[prepare_for_testing $testfile.exp $testfile \ + $srcfile {debug c++ additional_flags=-std=c++11}]} { + return -1 +} + +if ![runto_main] { + retur -1 +} + +gdb_breakpoint [gdb_get_line_number "a-is-ready"] +gdb_continue_to_breakpoint "a-is-ready" ".* a-is-ready .*" + +set test "print (struct C &&) a" +gdb_test_multiple $test $test { + -re " = \\(C &&\\) @0x\[0-9a-f\]+: {i = 42}\r\n$gdb_prompt $" { + pass $test + } + -re " = \\(C &\\) @0x\[0-9a-f\]+: {i = 42}\r\n$gdb_prompt $" { + kfail c++/16043 $test + } +} + +gdb_breakpoint [gdb_get_line_number "o-is-ready"] +gdb_continue_to_breakpoint "o-is-ready" ".* o-is-ready .*" + +set test "print o" +gdb_test_multiple $test $test { + -re " = \\(C &&\\) @0x\[0-9a-f\]+: {i = 42}\r\n$gdb_prompt $" { + pass $test + } + -re " = \\(C &\\) @0x\[0-9a-f\]+: {i = 42}\r\n$gdb_prompt $" { + kfail c++/16043 $test + } +}