From: Jim Ingham Date: Wed, 10 Apr 2002 00:11:51 +0000 (+0000) Subject: 2002-04-04 Jim Ingham X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ca439ad26a484e0a818095509fb57f8ef0b98314;p=binutils-gdb.git 2002-04-04 Jim Ingham * valarith.c (find_size_for_pointer_math): New function, either returns the size for a pointer's target, returns 1 for void *, or errors for incomplete types. (value_add, value_sub): use find_size_for_pointer_math. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 5b1be44084f..2ead05ff63f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2002-04-04 Jim Ingham + + * valarith.c (find_size_for_pointer_math): New function, either returns + the size for a pointer's target, returns 1 for void *, or errors for + incomplete types. + (value_add, value_sub): use find_size_for_pointer_math. + 2002-04-09 Daniel Jacobowitz * linux-low.c (linux_look_up_symbols): New hook. diff --git a/gdb/valarith.c b/gdb/valarith.c index c3d537a1923..cc067cb4b51 100644 --- a/gdb/valarith.c +++ b/gdb/valarith.c @@ -43,12 +43,50 @@ static struct value *value_subscripted_rvalue (struct value *, struct value *, i void _initialize_valarith (void); +/* Given a pointer, return the size of its target. + If the pointer type is void *, then return 1. + If the target type is incomplete, then error out. + This isn't a general purpose function, but just a + helper for value_sub & value_add. +*/ + +static LONGEST +find_size_for_pointer_math (struct type *ptr_type) +{ + LONGEST sz = -1; + struct type *ptr_target; + + ptr_target = check_typedef (TYPE_TARGET_TYPE (ptr_type)); + + sz = TYPE_LENGTH (ptr_target); + if (sz == 0) + { + if (TYPE_CODE (ptr_type) == TYPE_CODE_VOID) + sz = 1; + else + { + char *name; + + name = TYPE_NAME (ptr_target); + if (name == NULL) + name = TYPE_TAG_NAME (ptr_target); + if (name == NULL) + error ("Cannot perform pointer math on incomplete types, " + "try casting to a known type, or void *."); + else + error ("Cannot perform pointer math on incomplete type \"%s\", " + "try casting to a known type, or void *.", name); + } + } + return sz; +} + struct value * value_add (struct value *arg1, struct value *arg2) { struct value *valint; struct value *valptr; - register int len; + LONGEST sz; struct type *type1, *type2, *valptrtype; COERCE_NUMBER (arg1); @@ -77,12 +115,12 @@ value_add (struct value *arg1, struct value *arg2) valint = arg1; valptrtype = type2; } - len = TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (valptrtype))); - if (len == 0) - len = 1; /* For (void *) */ + + sz = find_size_for_pointer_math (valptrtype); + retval = value_from_pointer (valptrtype, value_as_address (valptr) - + (len * value_as_long (valint))); + + (sz * value_as_long (valint))); VALUE_BFD_SECTION (retval) = VALUE_BFD_SECTION (valptr); return retval; } @@ -104,7 +142,8 @@ value_sub (struct value *arg1, struct value *arg2) if (TYPE_CODE (type2) == TYPE_CODE_INT) { /* pointer - integer. */ - LONGEST sz = TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type1))); + LONGEST sz = find_size_for_pointer_math (type1); + return value_from_pointer (type1, (value_as_address (arg1) - (sz * value_as_long (arg2))));