]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
* dwarf2expr.c (get_signed_type): New function.
authorTom Tromey <tromey@redhat.com>
Fri, 3 Jun 2011 14:57:29 +0000 (14:57 +0000)
committerTom Tromey <tromey@redhat.com>
Fri, 3 Jun 2011 14:57:29 +0000 (14:57 +0000)
(execute_stack_op) <DW_OP_shra>: Always perform a signed shift.

gdb/ChangeLog
gdb/dwarf2expr.c

index 182909d482e44e3c0750a95feaac6207d8dfa227..97a30af6abb0152c3a7b670bd722a47408405d2f 100644 (file)
@@ -1,3 +1,8 @@
+2011-06-03  Tom Tromey  <tromey@redhat.com>
+
+       * dwarf2expr.c (get_signed_type): New function.
+       (execute_stack_op) <DW_OP_shra>: Always perform a signed shift.
+
 2011-06-02  Keith Seitz  <keiths@redhat.com>
 
        * objc-lang.c (find_methods): Increment objfile_csym earlier.
index 5cd33a6df84dd61c51b1b9fd5b3d151ec79a7c67..3c60b6ab1b41b3383171b7e811304fd5aeb82be0 100644 (file)
@@ -229,6 +229,28 @@ get_unsigned_type (struct gdbarch *gdbarch, struct type *type)
     }
 }
 
+/* Return the signed form of TYPE.  TYPE is necessarily an integral
+   type.  */
+
+static struct type *
+get_signed_type (struct gdbarch *gdbarch, struct type *type)
+{
+  switch (TYPE_LENGTH (type))
+    {
+    case 1:
+      return builtin_type (gdbarch)->builtin_int8;
+    case 2:
+      return builtin_type (gdbarch)->builtin_int16;
+    case 4:
+      return builtin_type (gdbarch)->builtin_int32;
+    case 8:
+      return builtin_type (gdbarch)->builtin_int64;
+    default:
+      error (_("no signed variant found for type, while evaluating "
+              "DWARF expression"));
+    }
+}
+
 /* Retrieve the N'th item on CTX's stack, converted to an address.  */
 
 CORE_ADDR
@@ -996,7 +1018,19 @@ execute_stack_op (struct dwarf_expr_context *ctx,
              case DW_OP_shra:
                dwarf_require_integral (value_type (first));
                dwarf_require_integral (value_type (second));
+               if (TYPE_UNSIGNED (value_type (first)))
+                 {
+                   struct type *stype
+                     = get_signed_type (ctx->gdbarch, value_type (first));
+
+                   first = value_cast (stype, first);
+                 }
+
                result_val = value_binop (first, second, BINOP_RSH);
+               /* Make sure we wind up with the same type we started
+                  with.  */
+               if (value_type (result_val) != value_type (second))
+                 result_val = value_cast (value_type (second), result_val);
                break;
              case DW_OP_xor:
                dwarf_require_integral (value_type (first));