This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

PATCH: fix for parsing hex floats


This patch, authored by Ulrich Weigand, improves parsing of  hexadecimal
floating point constants on targets with various rounding modes.  Tested
with a bootstrap and regression testsuite run on powerpc-linux.  OK for
the trunk?

Ben


2007-10-31  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>

	* c-cppbuiltin.c (builtin_define_with_hex_fp_value): Depending on
	the default target rounding mode, the decimal string we get may
	convert back to a different number when read back by the parser.
	Try to remedy this.

Index: c-cppbuiltin.c
===================================================================
--- c-cppbuiltin.c      (revision 129781)
+++ c-cppbuiltin.c      (working copy)
@@ -840,7 +840,7 @@ builtin_define_with_hex_fp_value (const 
                                  const char *fp_suffix,
                                  const char *fp_cast)
 {
-  REAL_VALUE_TYPE real;
+  REAL_VALUE_TYPE real, real2;
   char dec_str[64], buf1[256], buf2[256];
 
   /* Hex values are really cool and convenient, except that they're
@@ -856,6 +856,39 @@ builtin_define_with_hex_fp_value (const 
   real_from_string (&real, hex_str);
   real_to_decimal (dec_str, &real, sizeof (dec_str), digits, 0);
 
+  /* Depending on the default target rounding mode, the decimal string
+     we get may convert back to a different number when read back by
+     the parser.  Try to remedy this.  */
+
+  real_from_string (&real2, dec_str);
+  real_convert (&real2, TYPE_MODE (type), &real2);
+  if (!real_identical (&real2, &real))
+    {
+      char *p = dec_str;
+      while (ISDIGIT (*p))
+        p++;
+      if (*p == '.')
+        {
+          p++;
+          while (ISDIGIT (p[1]))
+           p++;
+        }
+
+      if (ISDIGIT (*p))
+       {
+         while (*p == '9')
+           {
+             *p-- = '0';
+             gcc_assert (p > dec_str && ISDIGIT (*p));
+           }
+         *p = *p + 1;
+       }
+
+      real_from_string (&real2, dec_str);
+      real_convert (&real2, TYPE_MODE (type), &real2);
+    }
+  gcc_assert (real_identical (&real2, &real));
+
   /* Assemble the macro in the following fashion
      macro = fp_cast [dec_str fp_suffix] */
   sprintf (buf1, "%s%s", dec_str, fp_suffix);



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