Fix bug in fixed-point handling
authorTom Tromey <tromey@adacore.com>
Tue, 18 Jul 2023 16:02:14 +0000 (10:02 -0600)
committerTom Tromey <tromey@adacore.com>
Mon, 31 Jul 2023 16:48:00 +0000 (10:48 -0600)
Alexandre Oliva found a bug in gdb's handling of fixed-point -- a
certain Ada fixed-point type would be misintepreted.  The bug was that
the DW_AT_small looked like:

 <1><13cd>: Abbrev Number: 16 (DW_TAG_constant)
    <13ce>   DW_AT_GNU_numerator: 1
    <13cf>   DW_AT_GNU_denominator: 0x8000000000000000

... but gdb interpreted the denominator as a negative value.

gdb/dwarf2/read.c
gdb/testsuite/gdb.ada/fixed_points.exp
gdb/testsuite/gdb.ada/fixed_points/fixed_points.adb

index b1f1c1d7257bc0220b30ddd5d381627a66151a8a..61730f6481c219ee0baf3049f402cf970483f3d0 100644 (file)
@@ -14867,6 +14867,8 @@ 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 ())
+    *value = gdb_mpz (attr->as_unsigned ());
   else
     *value = gdb_mpz (attr->constant_value (1));
 }
index ed61cab4bec14064544323704bc20b00bcd1fd51..2edc63f40717b81e58cd240785a70f464546f2f3 100644 (file)
@@ -91,4 +91,7 @@ foreach_with_prefix scenario {all minimal} {
     if {$scenario == "minimal" && [test_compiler_info {gcc-11-*}]} {
        gdb_test "print fp5_var" " = 3e-19"
     }
+
+    gdb_test "p Float(Another_Fixed) = Float(Another_Delta * 5)" "true" \
+       "value of another_fixed"
 }
index 67d38f2770b6816fce9607bfbf9fce22c5d0c52b..edcbac80ef9d423c37cbad091df07d906306b5ce 100644 (file)
@@ -57,6 +57,13 @@ procedure Fixed_Points is
 
    FP5_Var : FP5_Type := 3 * Delta5;
 
+
+   Another_Delta : constant := 1.0/(2**63);
+   type Another_Type is delta Another_Delta range -1.0 .. (1.0 - Another_Delta);
+   for  Another_Type'small use Another_Delta;
+   for  Another_Type'size  use 64;
+   Another_Fixed : Another_Type := Another_Delta * 5;
+
 begin
    Base_Object := 1.0/16.0;   -- Set breakpoint here
    Subtype_Object := 1.0/16.0;
@@ -67,4 +74,5 @@ begin
    Do_Nothing (FP3_Var'Address);
    Do_Nothing (FP4_Var'Address);
    Do_Nothing (FP5_Var'Address);
+   Do_Nothing (Another_Fixed'Address);
 end Fixed_Points;