This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[commit/Ada] Displaying wrong value for fixed point


A customer reported the fact that GDB was printing the wrong value
for some fixed point variables.

Jerome Guitton did the investigation and file the following
explaination:

| The problem appears when the significant figures of the
| delta cannot be stored into a long. Typically, 0.782778865 is OK,
| while 0.7827788651 is not.

This is related to the way fixed point types are encoded with GNAT,
and the way we implemented the handling of that encoding. See
exp_dbug.ads in the GNAT sources:

      --   Fixed-point types are encoded using a suffix that indicates the
      --   delta and small values. The actual type itself is a normal
      --   integer type.

      --     typ___XF_nn_dd
      --     typ___XF_nn_dd_nn_dd

      --   The first form is used when small = delta. The value of delta (and
      --   small) is given by the rational nn/dd, where nn and dd are decimal
      --   integers.
      --
      --   The second form is used if the small value is different from the
      --   delta. In this case, the first nn/dd rational value is for delta,
      --   and the second value is for small.

The patch explains further what the problem was, and what we did
in order to fix the problem.

2009-03-12  Jerome Guitton  <guitton@adacore.com>

        * ada-lang.c (ada_delta): Change the type of numerators and
        denominators to DOUBLEST, as they may not fit into a long.
        (scaling_factor): Ditto.

Tested on amd64-linux. Checked in.

We have a testcase in AdaCore's testsuite, but I'm not sure whether
we can submit it or whether the code is confidential. So I'll stay
on the safe side, and ask Jerome to take a look at whether we can
submit a testcase or not.

-- 
Joel
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 0ec724f..aa5dece 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -9296,12 +9296,16 @@ DOUBLEST
 ada_delta (struct type *type)
 {
   const char *encoding = fixed_type_info (type);
-  long num, den;
+  DOUBLEST num, den;
 
-  if (sscanf (encoding, "_%ld_%ld", &num, &den) < 2)
+  /* Strictly speaking, num and den are encoded as integer.  However,
+     they may not fit into a long, and they will have to be converted
+     to DOUBLEST anyway.  So scan them as DOUBLEST.  */
+  if (sscanf (encoding, "_%" DOUBLEST_SCAN_FORMAT "_%" DOUBLEST_SCAN_FORMAT,
+	      &num, &den) < 2)
     return -1.0;
   else
-    return (DOUBLEST) num / (DOUBLEST) den;
+    return num / den;
 }
 
 /* Assuming that ada_is_fixed_point_type (TYPE), return the scaling
@@ -9311,17 +9315,23 @@ static DOUBLEST
 scaling_factor (struct type *type)
 {
   const char *encoding = fixed_type_info (type);
-  unsigned long num0, den0, num1, den1;
+  DOUBLEST num0, den0, num1, den1;
   int n;
 
-  n = sscanf (encoding, "_%lu_%lu_%lu_%lu", &num0, &den0, &num1, &den1);
+  /* Strictly speaking, num's and den's are encoded as integer.  However,
+     they may not fit into a long, and they will have to be converted
+     to DOUBLEST anyway.  So scan them as DOUBLEST.  */
+  n = sscanf (encoding,
+	      "_%" DOUBLEST_SCAN_FORMAT "_%" DOUBLEST_SCAN_FORMAT
+	      "_%" DOUBLEST_SCAN_FORMAT "_%" DOUBLEST_SCAN_FORMAT,
+	      &num0, &den0, &num1, &den1);
 
   if (n < 2)
     return 1.0;
   else if (n == 4)
-    return (DOUBLEST) num1 / (DOUBLEST) den1;
+    return num1 / den1;
   else
-    return (DOUBLEST) num0 / (DOUBLEST) den0;
+    return num0 / den0;
 }
 
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]