[08/13] Use correct sign in get_mpz

Message ID 20250320-attribute-madness-v1-8-79d42789f881@adacore.com
State New
Headers
Series More work on DW_FORM_* and sign handling |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 fail Patch failed to apply
linaro-tcwg-bot/tcwg_gdb_build--master-arm fail Patch failed to apply

Commit Message

Tom Tromey March 20, 2025, 7:27 p.m. UTC
  This changes dwarf2/read.c:get_mpz to use the correct sign-extension
function.  Normally a rational constant uses signed values, but a
purely unsigned form also seems fine here.  This adds a new
attribute::form_is_strictly_unsigned, which is more precise than
form_is_unsigned (which accepts a lot of forms that aren't really for
ordinary constants).

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32680
---
 gdb/dwarf2/attribute.h | 9 +++++++++
 gdb/dwarf2/read.c      | 4 ++--
 2 files changed, 11 insertions(+), 2 deletions(-)
  

Patch

diff --git a/gdb/dwarf2/attribute.h b/gdb/dwarf2/attribute.h
index 6f321a53844141f408f45e99f16608eb86f33e6b..3150325db75e74328e858e8d2fdf09881bbb5110 100644
--- a/gdb/dwarf2/attribute.h
+++ b/gdb/dwarf2/attribute.h
@@ -173,6 +173,15 @@  struct attribute
      false.  */
   bool form_is_strictly_signed () const;
 
+  /* Check if the attribute's form is an unsigned constant form.  This
+     only returns true for forms that are strictly unsigned -- that
+     is, for a context-dependent form like DW_FORM_data1, this returns
+     false.  */
+  bool form_is_strictly_unsigned () const
+  {
+    return form == DW_FORM_udata;
+  }
+
   /* Check if the attribute's form is a form that requires
      "reprocessing".  */
   bool form_requires_reprocessing () const;
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index eabe07107d9ac01c3a4403d45b75f7ebcfd57d78..e6ab3c8b596f3fc1c627efd6e9e7146fb40a3575 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -13350,10 +13350,10 @@  get_mpz (struct dwarf2_cu *cu, gdb_mpz *value, struct attribute *attr)
 		   ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE,
 		   true);
     }
-  else if (attr->form_is_unsigned ())
+  else if (attr->form_is_strictly_unsigned ())
     *value = gdb_mpz (attr->as_unsigned ());
   else
-    *value = gdb_mpz (attr->constant_value (1));
+    *value = gdb_mpz (attr->signed_constant ().value_or (1));
 }
 
 /* Assuming DIE is a rational DW_TAG_constant, read the DIE's