This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Support C++11 rvalue (move constructor)


Hi,

currently one cannot debug C++11 move constructors, one gets:

# in C::C (C &&o)
(gdb) print o
$1 = <unknown type in .../testsuite/gdb.cp/rvalue, CU 0x0, DIE 0x1f6c>

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  <jan.kratochvil@redhat.com>

	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  <jan.kratochvil@redhat.com>

	* 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 <http://www.gnu.org/licenses/>.  */
+
+#include <memory>
+
+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 <http://www.gnu.org/licenses/>.
+
+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
+    }
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]