This is the mail archive of the gdb-cvs@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]

[binutils-gdb] Fix ptype of Rust slices


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=b3e3859bc577db5b79bb3d39048fd46c0a0420ef

commit b3e3859bc577db5b79bb3d39048fd46c0a0420ef
Author: Tom Tromey <tom@tromey.com>
Date:   Mon Oct 2 13:47:15 2017 -0600

    Fix ptype of Rust slices
    
    Something like "ptype &x[..]" (where "x" was a slice) would crash gdb.
    rust_subscript wasn't handling slicing in the EVAL_AVOID_SIDE_EFFECTS
    case.
    
    2017-10-02  Tom Tromey  <tom@tromey.com>
    
    	* rust-lang.c (rust_subscript): Handle slices in
    	EVAL_AVOID_SIDE_EFFECTS case.
    
    2017-10-02  Tom Tromey  <tom@tromey.com>
    
    	* gdb.rust/simple.exp: Test ptype of a slice.

Diff:
---
 gdb/ChangeLog                     |  5 +++++
 gdb/rust-lang.c                   | 42 ++++++++++++++++++++++++++++++++++++---
 gdb/testsuite/ChangeLog           |  4 ++++
 gdb/testsuite/gdb.rust/simple.exp | 19 ++++++++++++++++++
 4 files changed, 67 insertions(+), 3 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index a8820c8..11c1ca3 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,10 @@
 2017-10-02  Tom Tromey  <tom@tromey.com>
 
+	* rust-lang.c (rust_subscript): Handle slices in
+	EVAL_AVOID_SIDE_EFFECTS case.
+
+2017-10-02  Tom Tromey  <tom@tromey.com>
+
 	* rust-lang.c (rust_slice_type_p): Recognize &str as a slice type.
 
 2017-10-02  Tom Tromey  <tom@tromey.com>
diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c
index a9895fe..9b64efa 100644
--- a/gdb/rust-lang.c
+++ b/gdb/rust-lang.c
@@ -1456,17 +1456,53 @@ rust_subscript (struct expression *exp, int *pos, enum noside noside,
   else
     low = value_as_long (rhs);
 
+  struct type *type = check_typedef (value_type (lhs));
   if (noside == EVAL_AVOID_SIDE_EFFECTS)
     {
-      struct type *type = check_typedef (value_type (lhs));
+      struct type *base_type = nullptr;
+      if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+	base_type = TYPE_TARGET_TYPE (type);
+      else if (rust_slice_type_p (type))
+	{
+	  for (int i = 0; i < TYPE_NFIELDS (type); ++i)
+	    {
+	      if (strcmp (TYPE_FIELD_NAME (type, i), "data_ptr") == 0)
+		{
+		  base_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, i));
+		  break;
+		}
+	    }
+	  if (base_type == nullptr)
+	    error (_("Could not find 'data_ptr' in slice type"));
+	}
+      else if (TYPE_CODE (type) == TYPE_CODE_PTR)
+	base_type = TYPE_TARGET_TYPE (type);
+      else
+	error (_("Cannot subscript non-array type"));
+
+      struct type *new_type;
+      if (want_slice)
+	{
+	  if (rust_slice_type_p (type))
+	    new_type = type;
+	  else
+	    {
+	      struct type *usize
+		= language_lookup_primitive_type (exp->language_defn,
+						  exp->gdbarch,
+						  "usize");
+	      new_type = rust_slice_type ("&[*gdb*]", base_type, usize);
+	    }
+	}
+      else
+	new_type = base_type;
 
-      result = value_zero (TYPE_TARGET_TYPE (type), VALUE_LVAL (lhs));
+      return value_zero (new_type, VALUE_LVAL (lhs));
     }
   else
     {
       LONGEST low_bound;
       struct value *base;
-      struct type *type = check_typedef (value_type (lhs));
 
       if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
 	{
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index edc5079..296878c 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,9 @@
 2017-10-02  Tom Tromey  <tom@tromey.com>
 
+	* gdb.rust/simple.exp: Test ptype of a slice.
+
+2017-10-02  Tom Tromey  <tom@tromey.com>
+
 	* gdb.rust/simple.exp: Test index of slice.
 
 2017-09-27  Tom Tromey  <tom@tromey.com>
diff --git a/gdb/testsuite/gdb.rust/simple.exp b/gdb/testsuite/gdb.rust/simple.exp
index 1a46317..b01841f 100644
--- a/gdb/testsuite/gdb.rust/simple.exp
+++ b/gdb/testsuite/gdb.rust/simple.exp
@@ -85,6 +85,25 @@ gdb_test "print fromslice" " = 3"
 gdb_test "print slice\[0\]" " = 3"
 gdb_test "print slice as &\[i32\]\[0\]" " = 3"
 
+gdb_test_sequence "ptype slice" "" {
+    " = struct &\\\[i32\\\] \\{"
+    "  data_ptr: i32 \\*,"
+    "  length: usize,"
+    "\\}"
+}
+gdb_test_sequence "ptype &slice\[..\]" "" {
+    " = struct &\\\[i32\\\] \\{"
+    "  data_ptr: i32 \\*,"
+    "  length: usize,"
+    "\\}"
+}
+gdb_test_sequence "ptype &b\[..\]" "" {
+    " = struct &\\\[\\*gdb\\*\\\] \\{"
+    "  data_ptr: i32 \\*,"
+    "  length: usize,"
+    "\\}"
+}
+
 gdb_test "print x" " = \\(23, 25\\.5\\)"
 gdb_test "ptype x" " = \\(i32, f64\\)"
 gdb_test "print x as (i32,f64)" " = \\(23, 25\\.5\\)"


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