/* Perform arithmetic and other operations on values, for GDB.
- Copyright (C) 1986-2020 Free Software Foundation, Inc.
+ Copyright (C) 1986-2021 Free Software Foundation, Inc.
This file is part of GDB.
|| tarray->code () == TYPE_CODE_STRING)
{
struct type *range_type = tarray->index_type ();
- LONGEST lowerbound, upperbound;
+ gdb::optional<LONGEST> lowerbound = get_discrete_low_bound (range_type);
+ if (!lowerbound.has_value ())
+ lowerbound = 0;
- get_discrete_bounds (range_type, &lowerbound, &upperbound);
if (VALUE_LVAL (array) != lval_memory)
- return value_subscripted_rvalue (array, index, lowerbound);
+ return value_subscripted_rvalue (array, index, *lowerbound);
if (!c_style)
{
- if (index >= lowerbound && index <= upperbound)
- return value_subscripted_rvalue (array, index, lowerbound);
+ gdb::optional<LONGEST> upperbound
+ = get_discrete_high_bound (range_type);
+
+ if (!upperbound.has_value ())
+ upperbound = 0;
+
+ if (index >= *lowerbound && index <= *upperbound)
+ return value_subscripted_rvalue (array, index, *lowerbound);
+
/* Emit warning unless we have an array of unknown size.
An array of unknown size has lowerbound 0 and upperbound -1. */
- if (upperbound > -1)
+ if (*upperbound > -1)
warning (_("array or string index out of range"));
/* fall doing C stuff */
c_style = true;
}
- index -= lowerbound;
+ index -= *lowerbound;
array = value_coerce_array (array);
}
LONGEST stride = array_type->bit_stride ();
if (stride != 0)
{
- struct gdbarch *arch = get_type_arch (elt_type);
+ struct gdbarch *arch = elt_type->arch ();
int unit_size = gdbarch_addressable_memory_unit_size (arch);
elt_size = stride / (unit_size * 8);
}
struct value *
value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside)
{
- struct gdbarch *gdbarch = get_type_arch (value_type (arg1));
+ struct gdbarch *gdbarch = value_type (arg1)->arch ();
char *ptr;
char tstr[13], mangle_tstr[13];
int static_memfuncp, nargs;
{
struct type *type1 = check_typedef (value_type (arg1));
struct type *type2 = check_typedef (value_type (arg2));
+ const struct language_defn *language = current_language;
+ struct gdbarch *gdbarch = type1->arch ();
struct value *val;
+ gdb_mpq v1, v2, res;
+
gdb_assert (is_fixed_point_type (type1) || is_fixed_point_type (type2));
- if (!is_fixed_point_type (type1))
+ if (op == BINOP_MUL || op == BINOP_DIV)
{
- arg1 = value_cast (type2, arg1);
- type1 = type2;
+ v1 = value_to_gdb_mpq (arg1);
+ v2 = value_to_gdb_mpq (arg2);
+
+ /* The code below uses TYPE1 for the result type, so make sure
+ it is set properly. */
+ if (!is_fixed_point_type (type1))
+ type1 = type2;
}
- if (!is_fixed_point_type (type2))
+ else
{
- arg2 = value_cast (type1, arg2);
- type2 = type1;
+ if (!is_fixed_point_type (type1))
+ {
+ arg1 = value_cast (type2, arg1);
+ type1 = type2;
+ }
+ if (!is_fixed_point_type (type2))
+ {
+ arg2 = value_cast (type1, arg2);
+ type2 = type1;
+ }
+
+ v1.read_fixed_point (gdb::make_array_view (value_contents (arg1),
+ TYPE_LENGTH (type1)),
+ type_byte_order (type1), type1->is_unsigned (),
+ type1->fixed_point_scaling_factor ());
+ v2.read_fixed_point (gdb::make_array_view (value_contents (arg2),
+ TYPE_LENGTH (type2)),
+ type_byte_order (type2), type2->is_unsigned (),
+ type2->fixed_point_scaling_factor ());
}
- gdb_mpq v1, v2, res;
- v1.read_fixed_point (value_contents (arg1), TYPE_LENGTH (type1),
- type_byte_order (type1), type1->is_unsigned (),
- fixed_point_scaling_factor (type1));
- v2.read_fixed_point (value_contents (arg2), TYPE_LENGTH (type2),
- type_byte_order (type2), type2->is_unsigned (),
- fixed_point_scaling_factor (type2));
-
-#define INIT_VAL_WITH_FIXED_POINT_VAL(RESULT) \
- do { \
- val = allocate_value (type1); \
- (RESULT).write_fixed_point \
- (value_contents_raw (val), TYPE_LENGTH (type1), \
- type_byte_order (type1), type1->is_unsigned (), \
- fixed_point_scaling_factor (type1)); \
- } while (0)
+ auto fixed_point_to_value = [type1] (const gdb_mpq &fp)
+ {
+ value *fp_val = allocate_value (type1);
+
+ fp.write_fixed_point
+ (gdb::make_array_view (value_contents_raw (fp_val),
+ TYPE_LENGTH (type1)),
+ type_byte_order (type1),
+ type1->is_unsigned (),
+ type1->fixed_point_scaling_factor ());
+
+ return fp_val;
+ };
switch (op)
{
case BINOP_ADD:
mpq_add (res.val, v1.val, v2.val);
- INIT_VAL_WITH_FIXED_POINT_VAL (res);
+ val = fixed_point_to_value (res);
break;
case BINOP_SUB:
mpq_sub (res.val, v1.val, v2.val);
- INIT_VAL_WITH_FIXED_POINT_VAL (res);
+ val = fixed_point_to_value (res);
break;
case BINOP_MIN:
- INIT_VAL_WITH_FIXED_POINT_VAL (mpq_cmp (v1.val, v2.val) < 0 ? v1 : v2);
+ val = fixed_point_to_value (mpq_cmp (v1.val, v2.val) < 0 ? v1 : v2);
break;
case BINOP_MAX:
- INIT_VAL_WITH_FIXED_POINT_VAL (mpq_cmp (v1.val, v2.val) > 0 ? v1 : v2);
+ val = fixed_point_to_value (mpq_cmp (v1.val, v2.val) > 0 ? v1 : v2);
break;
case BINOP_MUL:
mpq_mul (res.val, v1.val, v2.val);
- INIT_VAL_WITH_FIXED_POINT_VAL (res);
+ val = fixed_point_to_value (res);
break;
case BINOP_DIV:
+ if (mpq_sgn (v2.val) == 0)
+ error (_("Division by zero"));
mpq_div (res.val, v1.val, v2.val);
- INIT_VAL_WITH_FIXED_POINT_VAL (res);
+ val = fixed_point_to_value (res);
+ break;
+
+ case BINOP_EQUAL:
+ val = value_from_ulongest (language_bool_type (language, gdbarch),
+ mpq_cmp (v1.val, v2.val) == 0 ? 1 : 0);
+ break;
+
+ case BINOP_LESS:
+ val = value_from_ulongest (language_bool_type (language, gdbarch),
+ mpq_cmp (v1.val, v2.val) < 0 ? 1 : 0);
break;
default:
struct type *comp_type = promotion_type (value_type (arg1_real),
value_type (arg2_real));
+ if (!can_create_complex_type (comp_type))
+ error (_("Argument to complex arithmetic operation not supported."));
+
arg1_real = value_cast (comp_type, arg1_real);
arg1_imag = value_cast (comp_type, arg1_imag);
arg2_real = value_cast (comp_type, arg2_real);
is_int1 = is_integral_type (type1);
is_int2 = is_integral_type (type2);
- if (is_int1 && is_int2)
+ if ((is_int1 && is_int2)
+ || (is_fixed_point_type (type1) && is_fixed_point_type (type2)))
return longest_to_int (value_as_long (value_binop (arg1, arg2,
BINOP_LESS)));
else if ((is_floating_value (arg1) || is_int1)
int
value_bit_index (struct type *type, const gdb_byte *valaddr, int index)
{
- struct gdbarch *gdbarch = get_type_arch (type);
+ struct gdbarch *gdbarch = type->arch ();
LONGEST low_bound, high_bound;
LONGEST word;
unsigned rel_index;
struct type *range = type->index_type ();
- if (get_discrete_bounds (range, &low_bound, &high_bound) < 0)
+ if (!get_discrete_bounds (range, &low_bound, &high_bound))
return -2;
if (index < low_bound || index > high_bound)
return -1;