aboutsummaryrefslogtreecommitdiff
path: root/gdb/rust-lang.c
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2017-10-02 13:47:15 -0600
committerTom Tromey <tom@tromey.com>2017-10-02 14:06:48 -0600
commitb3e3859bc577db5b79bb3d39048fd46c0a0420ef (patch)
treedd763223288447e29296b120520b709e4020dded /gdb/rust-lang.c
parent01af5e0d09ac9c621e7b280f44a2c7ef55784493 (diff)
downloadgdb-b3e3859bc577db5b79bb3d39048fd46c0a0420ef.zip
gdb-b3e3859bc577db5b79bb3d39048fd46c0a0420ef.tar.gz
gdb-b3e3859bc577db5b79bb3d39048fd46c0a0420ef.tar.bz2
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.
Diffstat (limited to 'gdb/rust-lang.c')
-rw-r--r--gdb/rust-lang.c42
1 files changed, 39 insertions, 3 deletions
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)
{