gdb: fix python/lib/gdb/__init__.py formatting
[deliverable/binutils-gdb.git] / gdb / valarith.c
index 7ab183cbdc45c3bc03e3959619748ce45132fd78..299a99f4703d0e7fd4ffa1c86888ca19a9c744ce 100644 (file)
@@ -1,6 +1,6 @@
 /* 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.
 
@@ -150,25 +150,33 @@ value_subscript (struct value *array, LONGEST index)
       || 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);
     }
 
@@ -194,7 +202,7 @@ value_subscripted_rvalue (struct value *array, LONGEST index, LONGEST lowerbound
   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);
     }
@@ -531,7 +539,7 @@ value_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op,
 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;
@@ -892,69 +900,89 @@ fixed_point_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
   struct type *type2 = check_typedef (value_type (arg2));
   const struct language_defn *language = current_language;
 
-  struct gdbarch *gdbarch = get_type_arch (type1);
+  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 (gdb::make_array_view (value_contents (arg1),
-                                            TYPE_LENGTH (type1)),
-                      type_byte_order (type1), type1->is_unsigned (),
-                      fixed_point_scaling_factor (type1));
-  v2.read_fixed_point (gdb::make_array_view (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                       \
-        (gdb::make_array_view (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:
@@ -1048,6 +1076,9 @@ complex_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
 
   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);
@@ -1939,13 +1970,13 @@ value_complement (struct value *arg1)
 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;
This page took 0.02675 seconds and 4 git commands to generate.