Fix ptype of Rust slices
authorTom Tromey <tom@tromey.com>
Mon, 2 Oct 2017 19:47:15 +0000 (13:47 -0600)
committerTom Tromey <tom@tromey.com>
Mon, 2 Oct 2017 20:06:48 +0000 (14:06 -0600)
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.

gdb/ChangeLog
gdb/rust-lang.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.rust/simple.exp

index a8820c8..11c1ca3 100644 (file)
@@ -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>
index a9895fe..9b64efa 100644 (file)
@@ -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)
        {
index edc5079..296878c 100644 (file)
@@ -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>
index 1a46317..b01841f 100644 (file)
@@ -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\\)"