From 89eef114606ca0510db54cec2fc60946a91990e8 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Thu, 11 Sep 2008 14:13:46 +0000 Subject: [PATCH] * value.h (value_add, value_sub): Remove. (value_ptradd, value_ptrsub, value_ptrdiff): Add prototypes. * valarith.c (value_add, value_sub): Remove. (value_ptradd, value_ptrsub, value_ptrdiff): New functions. (find_size_for_pointer_math): Add assertion. Update comment. (value_binop): Update comment. * eval.c (ptrmath_type_p): New function. (evaluate_subexp_standard): Replace value_add and value_sub by value_ptradd, value_ptrsub, value_ptrdiff or value_binop. Use builtin_type_uint8 instead of builtin_type_char to hold the increment for BINOP_{PRE,POST}{IN,DE}CREMENT operations. * valarith.c (value_subscript): Replace value_add by value_ptradd. Replace value_sub by value_binop. * ada-lang.c (ada_value_ptr_subscript): Likewise. (ada_tag_name_2): Replace value_add by value_ptradd. (ada_evaluate_subexp): Replace value_add and value_sub by value_binop. * m2-lang.c (evaluate_subexp_modula2): Replace value_add by value_ptradd. * gnu-v2-abi.c (gnuv2_virtual_fn_field): Likewise. * gnu-v3-abi.c (gnuv3_method_ptr_to_value): Likewise. --- gdb/ChangeLog | 25 ++++++++++ gdb/ada-lang.c | 13 ++++-- gdb/eval.c | 80 ++++++++++++++++++++++++++------ gdb/gnu-v2-abi.c | 2 +- gdb/gnu-v3-abi.c | 2 +- gdb/m2-lang.c | 2 +- gdb/valarith.c | 116 ++++++++++++++++++++--------------------------- gdb/value.h | 6 ++- 8 files changed, 156 insertions(+), 90 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 6a903b9bdc1..4d928c04a36 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,28 @@ +2008-09-11 Ulrich Weigand + + * value.h (value_add, value_sub): Remove. + (value_ptradd, value_ptrsub, value_ptrdiff): Add prototypes. + * valarith.c (value_add, value_sub): Remove. + (value_ptradd, value_ptrsub, value_ptrdiff): New functions. + (find_size_for_pointer_math): Add assertion. Update comment. + (value_binop): Update comment. + + * eval.c (ptrmath_type_p): New function. + (evaluate_subexp_standard): Replace value_add and value_sub + by value_ptradd, value_ptrsub, value_ptrdiff or value_binop. + Use builtin_type_uint8 instead of builtin_type_char to hold + the increment for BINOP_{PRE,POST}{IN,DE}CREMENT operations. + * valarith.c (value_subscript): Replace value_add by + value_ptradd. Replace value_sub by value_binop. + * ada-lang.c (ada_value_ptr_subscript): Likewise. + (ada_tag_name_2): Replace value_add by value_ptradd. + (ada_evaluate_subexp): Replace value_add and value_sub by + value_binop. + * m2-lang.c (evaluate_subexp_modula2): Replace value_add + by value_ptradd. + * gnu-v2-abi.c (gnuv2_virtual_fn_field): Likewise. + * gnu-v3-abi.c (gnuv3_method_ptr_to_value): Likewise. + 2008-09-11 Ulrich Weigand * eval.c (evaluate_subexp_for_sizeof): Use builtin_int type of diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index d7dddd05ab3..2142b164206 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -2362,8 +2362,10 @@ ada_value_ptr_subscript (struct value *arr, struct type *type, int arity, get_discrete_bounds (TYPE_INDEX_TYPE (type), &lwb, &upb); idx = value_pos_atr (ind[k]); if (lwb != 0) - idx = value_sub (idx, value_from_longest (builtin_type_int, lwb)); - arr = value_add (arr, idx); + idx = value_binop (idx, value_from_longest (value_type (idx), lwb), + BINOP_SUB); + + arr = value_ptradd (arr, idx); type = TYPE_TARGET_TYPE (type); } @@ -5726,7 +5728,8 @@ ada_tag_name_2 (struct tag_args *args) valp = value_cast (info_type, args->tag); if (valp == NULL) return 0; - val = value_ind (value_add (valp, value_from_longest (builtin_type_int, -1))); + val = value_ind (value_ptradd (valp, + value_from_longest (builtin_type_int8, -1))); if (val == NULL) return 0; val = ada_value_struct_elt (val, "expanded_name", 1); @@ -8460,7 +8463,7 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp, type = value_type (arg1); while (TYPE_CODE (type) == TYPE_CODE_REF) type = TYPE_TARGET_TYPE (type); - return value_cast (type, value_add (arg1, arg2)); + return value_cast (type, value_binop (arg1, arg2, BINOP_ADD)); case BINOP_SUB: arg1 = evaluate_subexp_with_coercion (exp, pos, noside); @@ -8481,7 +8484,7 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp, type = value_type (arg1); while (TYPE_CODE (type) == TYPE_CODE_REF) type = TYPE_TARGET_TYPE (type); - return value_cast (type, value_sub (arg1, arg2)); + return value_cast (type, value_binop (arg1, arg2, BINOP_SUB)); case BINOP_MUL: case BINOP_DIV: diff --git a/gdb/eval.c b/gdb/eval.c index 3c082c27196..d5536a285d8 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -439,6 +439,27 @@ value_f90_subarray (struct value *array, return value_slice (array, low_bound, high_bound - low_bound + 1); } +static int +ptrmath_type_p (struct type *type) +{ + type = check_typedef (type); + if (TYPE_CODE (type) == TYPE_CODE_REF) + type = TYPE_TARGET_TYPE (type); + + switch (TYPE_CODE (type)) + { + case TYPE_CODE_PTR: + case TYPE_CODE_FUNC: + return 1; + + case TYPE_CODE_ARRAY: + return current_language->c_style_arrays; + + default: + return 0; + } +} + struct value * evaluate_subexp_standard (struct type *expect_type, struct expression *exp, int *pos, @@ -1506,10 +1527,10 @@ evaluate_subexp_standard (struct type *expect_type, op = exp->elts[pc + 1].opcode; if (binop_user_defined_p (op, arg1, arg2)) return value_x_binop (arg1, arg2, BINOP_ASSIGN_MODIFY, op, noside); - else if (op == BINOP_ADD) - arg2 = value_add (arg1, arg2); - else if (op == BINOP_SUB) - arg2 = value_sub (arg1, arg2); + else if (op == BINOP_ADD && ptrmath_type_p (value_type (arg1))) + arg2 = value_ptradd (arg1, arg2); + else if (op == BINOP_SUB && ptrmath_type_p (value_type (arg1))) + arg2 = value_ptrsub (arg1, arg2); else arg2 = value_binop (arg1, arg2, op); return value_assign (arg1, arg2); @@ -1521,8 +1542,12 @@ evaluate_subexp_standard (struct type *expect_type, goto nosideret; if (binop_user_defined_p (op, arg1, arg2)) return value_x_binop (arg1, arg2, op, OP_NULL, noside); + else if (ptrmath_type_p (value_type (arg1))) + return value_ptradd (arg1, arg2); + else if (ptrmath_type_p (value_type (arg2))) + return value_ptradd (arg2, arg1); else - return value_add (arg1, arg2); + return value_binop (arg1, arg2, BINOP_ADD); case BINOP_SUB: arg1 = evaluate_subexp_with_coercion (exp, pos, noside); @@ -1531,8 +1556,19 @@ evaluate_subexp_standard (struct type *expect_type, goto nosideret; if (binop_user_defined_p (op, arg1, arg2)) return value_x_binop (arg1, arg2, op, OP_NULL, noside); + else if (ptrmath_type_p (value_type (arg1))) + { + if (ptrmath_type_p (value_type (arg2))) + { + /* FIXME -- should be ptrdiff_t */ + type = builtin_type (exp->gdbarch)->builtin_long; + return value_from_longest (type, value_ptrdiff (arg1, arg2)); + } + else + return value_ptrsub (arg1, arg2); + } else - return value_sub (arg1, arg2); + return value_binop (arg1, arg2, BINOP_SUB); case BINOP_EXP: case BINOP_MUL: @@ -2091,8 +2127,12 @@ evaluate_subexp_standard (struct type *expect_type, } else { - arg2 = value_add (arg1, value_from_longest (builtin_type_char, - (LONGEST) 1)); + arg2 = value_from_longest (builtin_type_uint8, (LONGEST) 1); + if (ptrmath_type_p (value_type (arg1))) + arg2 = value_ptradd (arg1, arg2); + else + arg2 = value_binop (arg1, arg2, BINOP_ADD); + return value_assign (arg1, arg2); } @@ -2106,8 +2146,12 @@ evaluate_subexp_standard (struct type *expect_type, } else { - arg2 = value_sub (arg1, value_from_longest (builtin_type_char, - (LONGEST) 1)); + arg2 = value_from_longest (builtin_type_uint8, (LONGEST) 1); + if (ptrmath_type_p (value_type (arg1))) + arg2 = value_ptrsub (arg1, arg2); + else + arg2 = value_binop (arg1, arg2, BINOP_SUB); + return value_assign (arg1, arg2); } @@ -2121,8 +2165,12 @@ evaluate_subexp_standard (struct type *expect_type, } else { - arg2 = value_add (arg1, value_from_longest (builtin_type_char, - (LONGEST) 1)); + arg2 = value_from_longest (builtin_type_uint8, (LONGEST) 1); + if (ptrmath_type_p (value_type (arg1))) + arg2 = value_ptradd (arg1, arg2); + else + arg2 = value_binop (arg1, arg2, BINOP_ADD); + value_assign (arg1, arg2); return arg1; } @@ -2137,8 +2185,12 @@ evaluate_subexp_standard (struct type *expect_type, } else { - arg2 = value_sub (arg1, value_from_longest (builtin_type_char, - (LONGEST) 1)); + arg2 = value_from_longest (builtin_type_uint8, (LONGEST) 1); + if (ptrmath_type_p (value_type (arg1))) + arg2 = value_ptrsub (arg1, arg2); + else + arg2 = value_binop (arg1, arg2, BINOP_SUB); + value_assign (arg1, arg2); return arg1; } diff --git a/gdb/gnu-v2-abi.c b/gdb/gnu-v2-abi.c index 76d5f133e87..771cc2b709f 100644 --- a/gdb/gnu-v2-abi.c +++ b/gdb/gnu-v2-abi.c @@ -151,7 +151,7 @@ gnuv2_virtual_fn_field (struct value **arg1p, struct fn_field * f, int j, else { /* Handle the case where the vtbl field points directly to a structure. */ - vtbl = value_add (vtbl, vi); + vtbl = value_ptradd (vtbl, vi); entry = value_ind (vtbl); } diff --git a/gdb/gnu-v3-abi.c b/gdb/gnu-v3-abi.c index ab77072b0e3..c28a7862609 100644 --- a/gdb/gnu-v3-abi.c +++ b/gdb/gnu-v3-abi.c @@ -675,7 +675,7 @@ gnuv3_method_ptr_to_value (struct value **this_p, struct value *method_ptr) instance. */ *this_p = value_cast (builtin_type_void_data_ptr, *this_p); adjval = value_from_longest (builtin_type_long, adjustment); - *this_p = value_add (*this_p, adjval); + *this_p = value_ptradd (*this_p, adjval); *this_p = value_cast (final_type, *this_p); if (vbit) diff --git a/gdb/m2-lang.c b/gdb/m2-lang.c index 793ae03a64d..5c3a2840a5c 100644 --- a/gdb/m2-lang.c +++ b/gdb/m2-lang.c @@ -251,7 +251,7 @@ evaluate_subexp_modula2 (struct type *expect_type, struct expression *exp, arg1 = value_cast (type, arg1); type = check_typedef (value_type (arg1)); - return value_ind (value_add (arg1, arg2)); + return value_ind (value_ptradd (arg1, arg2)); } else if (TYPE_CODE (type) != TYPE_CODE_ARRAY) diff --git a/gdb/valarith.c b/gdb/valarith.c index c13c3930328..b9daedf5bc6 100644 --- a/gdb/valarith.c +++ b/gdb/valarith.c @@ -50,7 +50,7 @@ void _initialize_valarith (void); 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. + helper for value_ptrsub & value_ptradd. */ static LONGEST @@ -59,6 +59,7 @@ find_size_for_pointer_math (struct type *ptr_type) LONGEST sz = -1; struct type *ptr_target; + gdb_assert (TYPE_CODE (ptr_type) == TYPE_CODE_PTR); ptr_target = check_typedef (TYPE_TARGET_TYPE (ptr_type)); sz = TYPE_LENGTH (ptr_target); @@ -84,90 +85,73 @@ find_size_for_pointer_math (struct type *ptr_type) return sz; } +/* Given a pointer ARG1 and an integral value ARG2, return the + result of C-style pointer arithmetic ARG1 + ARG2. */ + struct value * -value_add (struct value *arg1, struct value *arg2) +value_ptradd (struct value *arg1, struct value *arg2) { - struct value *valint; - struct value *valptr; + struct type *valptrtype; LONGEST sz; - struct type *type1, *type2, *valptrtype; arg1 = coerce_array (arg1); - arg2 = coerce_array (arg2); - type1 = check_typedef (value_type (arg1)); - type2 = check_typedef (value_type (arg2)); + valptrtype = check_typedef (value_type (arg1)); + sz = find_size_for_pointer_math (valptrtype); - if ((TYPE_CODE (type1) == TYPE_CODE_PTR - || TYPE_CODE (type2) == TYPE_CODE_PTR) - && - (is_integral_type (type1) || is_integral_type (type2))) - /* Exactly one argument is a pointer, and one is an integer. */ - { - struct value *retval; + if (!is_integral_type (value_type (arg2))) + error (_("Argument to arithmetic operation not a number or boolean.")); - if (TYPE_CODE (type1) == TYPE_CODE_PTR) - { - valptr = arg1; - valint = arg2; - valptrtype = type1; - } - else - { - valptr = arg2; - valint = arg1; - valptrtype = type2; - } + return value_from_pointer (valptrtype, + value_as_address (arg1) + + (sz * value_as_long (arg2))); +} - sz = find_size_for_pointer_math (valptrtype); +/* Given a pointer ARG1 and an integral value ARG2, return the + result of C-style pointer arithmetic ARG1 - ARG2. */ - retval = value_from_pointer (valptrtype, - value_as_address (valptr) - + (sz * value_as_long (valint))); - return retval; - } +struct value * +value_ptrsub (struct value *arg1, struct value *arg2) +{ + struct type *valptrtype; + LONGEST sz; - return value_binop (arg1, arg2, BINOP_ADD); + arg1 = coerce_array (arg1); + valptrtype = check_typedef (value_type (arg1)); + sz = find_size_for_pointer_math (valptrtype); + + if (!is_integral_type (value_type (arg2))) + error (_("Argument to arithmetic operation not a number or boolean.")); + + return value_from_pointer (valptrtype, + value_as_address (arg1) + - (sz * value_as_long (arg2))); } -struct value * -value_sub (struct value *arg1, struct value *arg2) +/* Given two compatible pointer values ARG1 and ARG2, return the + result of C-style pointer arithmetic ARG1 - ARG2. */ + +LONGEST +value_ptrdiff (struct value *arg1, struct value *arg2) { struct type *type1, *type2; + LONGEST sz; + arg1 = coerce_array (arg1); arg2 = coerce_array (arg2); type1 = check_typedef (value_type (arg1)); type2 = check_typedef (value_type (arg2)); - if (TYPE_CODE (type1) == TYPE_CODE_PTR) - { - if (is_integral_type (type2)) - { - /* pointer - integer. */ - LONGEST sz = find_size_for_pointer_math (type1); + gdb_assert (TYPE_CODE (type1) == TYPE_CODE_PTR); + gdb_assert (TYPE_CODE (type2) == TYPE_CODE_PTR); - return value_from_pointer (type1, - (value_as_address (arg1) - - (sz * value_as_long (arg2)))); - } - else if (TYPE_CODE (type2) == TYPE_CODE_PTR - && TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type1))) - == TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type2)))) - { - /* pointer to - pointer to . */ - LONGEST sz = TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type1))); - return value_from_longest - (builtin_type_long, /* FIXME -- should be ptrdiff_t */ - (value_as_long (arg1) - value_as_long (arg2)) / sz); - } - else - { - error (_("\ + if (TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type1))) + != TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type2)))) + error (_("\ First argument of `-' is a pointer and second argument is neither\n\ an integer nor a pointer of the same type.")); - } - } - return value_binop (arg1, arg2, BINOP_SUB); + sz = TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (type1))); + return (value_as_long (arg1) - value_as_long (arg2)) / sz; } /* Return the value of ARRAY[IDX]. @@ -216,15 +200,15 @@ value_subscript (struct value *array, struct value *idx) if (lowerbound != 0) { - bound = value_from_longest (builtin_type_int, (LONGEST) lowerbound); - idx = value_sub (idx, bound); + bound = value_from_longest (value_type (idx), (LONGEST) lowerbound); + idx = value_binop (idx, bound, BINOP_SUB); } array = value_coerce_array (array); } if (c_style) - return value_ind (value_add (array, idx)); + return value_ind (value_ptradd (array, idx)); else error (_("not an array or string")); } @@ -1176,7 +1160,7 @@ value_args_as_decimal (struct value *arg1, struct value *arg2, representations as integers or floats. This includes booleans, characters, integers, or floats. Does not support addition and subtraction on pointers; - use value_add or value_sub if you want to handle those possibilities. */ + use value_ptradd, value_ptrsub or value_ptrdiff for those operations. */ struct value * value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) diff --git a/gdb/value.h b/gdb/value.h index d0545e20d14..5ff84b34c28 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -331,9 +331,11 @@ extern struct value *value_concat (struct value *arg1, struct value *arg2); extern struct value *value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op); -extern struct value *value_add (struct value *arg1, struct value *arg2); +extern struct value *value_ptradd (struct value *arg1, struct value *arg2); -extern struct value *value_sub (struct value *arg1, struct value *arg2); +extern struct value *value_ptrsub (struct value *arg1, struct value *arg2); + +extern LONGEST value_ptrdiff (struct value *arg1, struct value *arg2); extern int value_must_coerce_to_target (struct value *arg1); -- 2.30.2