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

Re: [PATCH] Fix libstdc++/5045 (take3)


Testing passed.

Eventually I have slighty improved the version posted, considering the special case of 64 bit
unsigned integers (long or long long): for those digits10==max number of digits and + 1 is not
needed in the corresponding num_get::do_get.

This is the final version.

Cheers,
Paolo.

///////////////

2001-12-10  Paolo Carlini  <pcarlini@unitus.it>
            Philip Martin  <philip@codematters.co.uk>

        libstdc++/5045
        * include/bits/std_limits.h: Fix __glibcpp_XX_digits10 defines for
        integral types.
        * include/bits/locale_facets.tcc (num_get::do_get for integral types):
        Tweak _M_extract_int call.
        * testsuite/27_io/istream_extractor_arith.cc (test13, test12_aux): Tweak
        overflowing number of digits.
        * testsuite/18_support/numeric_limits.cc: Add testcase.

diff -urN libstdc++-v3-vanilla/include/bits/locale_facets.tcc
libstdc++-v3/include/bits/locale_facets.tcc
--- libstdc++-v3-vanilla/include/bits/locale_facets.tcc Mon Dec 10 14:37:55 2001
+++ libstdc++-v3/include/bits/locale_facets.tcc Tue Dec 11 00:07:30 2001
@@ -455,8 +455,14 @@
       // integral types.
       char __xtrc[32];
       int __base;
+      // According to 18.2.1.2.9, digits10 is "Number of base 10 digits
+      // that can be represented without change" so we have to add 1 to it
+      // in order to obtain the max number of digits. The same for the
+      // other do_get for integral types below (but 64 bit unsigned long
+      // or unsigned long long are special in that digits10 is identical
+      // to the max number of digits).
       _M_extract_int(__beg, __end, __io, __err, __xtrc,
-       numeric_limits<long>::digits10, __base);
+       numeric_limits<long>::digits10 + 1, __base);

       // Stage 2: convert and store results.
       char* __sanity;
@@ -482,7 +488,7 @@
       char __xtrc[32];
       int __base;
       _M_extract_int(__beg, __end, __io, __err, __xtrc,
-       numeric_limits<unsigned short>::digits10, __base);
+       numeric_limits<unsigned short>::digits10 + 1, __base);

       // Stage 2: convert and store results.
       char* __sanity;
@@ -509,7 +515,7 @@
       char __xtrc[32];
       int __base;
       _M_extract_int(__beg, __end, __io, __err, __xtrc,
-       numeric_limits<unsigned int>::digits10, __base);
+       numeric_limits<unsigned int>::digits10 + 1, __base);

       // Stage 2: convert and store results.
       char* __sanity;
@@ -535,9 +541,13 @@
       // integral types.
       char __xtrc[32];
       int __base;
+#if __glibcpp_long_bits == 64
       _M_extract_int(__beg, __end, __io, __err, __xtrc,
        numeric_limits<unsigned long>::digits10, __base);
-
+#else
+      _M_extract_int(__beg, __end, __io, __err, __xtrc,
+       numeric_limits<unsigned long>::digits10 + 1, __base);
+#endif
       // Stage 2: convert and store results.
       char* __sanity;
       errno = 0;
@@ -563,7 +573,7 @@
       char __xtrc[32];
       int __base;
       _M_extract_int(__beg, __end, __io, __err, __xtrc,
-       numeric_limits<long long>::digits10, __base);
+       numeric_limits<long long>::digits10 + 1, __base);

       // Stage 2: convert and store results.
       char* __sanity;
@@ -588,9 +598,13 @@
       // integral types.
       char __xtrc[32];
       int __base;
+#if __glibcpp_long_long_bits == 64
       _M_extract_int(__beg, __end, __io, __err, __xtrc,
        numeric_limits<unsigned long long>::digits10, __base);
-
+#else
+      _M_extract_int(__beg, __end, __io, __err, __xtrc,
+       numeric_limits<unsigned long long>::digits10 + 1, __base);
+#endif
       // Stage 2: convert and store results.
       char* __sanity;
       errno = 0;
@@ -718,7 +732,7 @@
       char __xtrc[32];
       int __base;
       _M_extract_int(__beg, __end, __io, __err, __xtrc,
-       numeric_limits<unsigned long>::digits10, __base);
+       numeric_limits<unsigned long>::digits10 + 1, __base);

       // Stage 2: convert and store results.
       char* __sanity;
diff -urN libstdc++-v3-vanilla/include/bits/std_limits.h libstdc++-v3/include/bits/std_limits.h

--- libstdc++-v3-vanilla/include/bits/std_limits.h Mon Dec 10 21:33:27 2001
+++ libstdc++-v3/include/bits/std_limits.h Mon Dec 10 21:34:02 2001
@@ -144,31 +144,31 @@
 #define __glibcpp_s8_max 127
 #define __glibcpp_s8_min (-__glibcpp_s8_max - 1)
 #define __glibcpp_s8_digits 7
-#define __glibcpp_s8_digits10 3
+#define __glibcpp_s8_digits10 2
 #define __glibcpp_u8_min 0U
 #define __glibcpp_u8_max (__glibcpp_s8_max * 2 + 1)
 #define __glibcpp_u8_digits 8
-#define __glibcpp_u8_digits10 3
+#define __glibcpp_u8_digits10 2
 #define __glibcpp_s16_max 32767
 #define __glibcpp_s16_min (-__glibcpp_s16_max - 1)
 #define __glibcpp_s16_digits 15
-#define __glibcpp_s16_digits10 5
+#define __glibcpp_s16_digits10 4
 #define __glibcpp_u16_min 0U
 #define __glibcpp_u16_max (__glibcpp_s16_max * 2 + 1)
 #define __glibcpp_u16_digits 16
-#define __glibcpp_u16_digits10 5
+#define __glibcpp_u16_digits10 4
 #define __glibcpp_s32_max 2147483647L
 #define __glibcpp_s32_min (-__glibcpp_s32_max - 1)
 #define __glibcpp_s32_digits 31
-#define __glibcpp_s32_digits10 10
+#define __glibcpp_s32_digits10 9
 #define __glibcpp_u32_min 0UL
 #define __glibcpp_u32_max (__glibcpp_s32_max * 2U + 1)
 #define __glibcpp_u32_digits 32
-#define __glibcpp_u32_digits10 10
+#define __glibcpp_u32_digits10 9
 #define __glibcpp_s64_max 9223372036854775807LL
 #define __glibcpp_s64_min (-__glibcpp_s64_max - 1)
 #define __glibcpp_s64_digits 63
-#define __glibcpp_s64_digits10 19
+#define __glibcpp_s64_digits10 18
 #define __glibcpp_u64_min 0ULL
 #define __glibcpp_u64_max (__glibcpp_s64_max * 2ULL + 1)
 #define __glibcpp_u64_digits 64
diff -urN libstdc++-v3-vanilla/testsuite/18_support/numeric_limits.cc
libstdc++-v3/testsuite/18_support/numeric_limits.cc
--- libstdc++-v3-vanilla/testsuite/18_support/numeric_limits.cc Sat Dec  8 01:25:59 2001
+++ libstdc++-v3/testsuite/18_support/numeric_limits.cc Sat Dec  8 10:53:49 2001
@@ -155,10 +155,32 @@
   const bool* pb1 = &b_nl_type::traps;
 }

+// libstdc++/5045
+bool test03()
+{
+  bool test = true;
+
+  VERIFY( __glibcpp_s8_digits10 == 2 );
+  VERIFY( __glibcpp_u8_digits10 == 2 );
+  VERIFY( __glibcpp_s16_digits10 == 4 );
+  VERIFY( __glibcpp_u16_digits10 == 4 );
+  VERIFY( __glibcpp_s32_digits10 == 9 );
+  VERIFY( __glibcpp_u32_digits10 == 9 );
+  VERIFY( __glibcpp_s64_digits10 == 18 );
+  VERIFY( __glibcpp_u64_digits10 == 19 );
+
+#ifdef DEBUG_ASSERT
+  assert(test);
+#endif
+
+  return test;
+}
+
 int main()
 {
   test01();
   test02();
+  test03();

   test_extrema<char>();
   test_extrema<signed char>();
diff -urN libstdc++-v3-vanilla/testsuite/27_io/istream_extractor_arith.cc
libstdc++-v3/testsuite/27_io/istream_extractor_arith.cc
--- libstdc++-v3-vanilla/testsuite/27_io/istream_extractor_arith.cc Mon Dec 10 14:37:55 2001
+++ libstdc++-v3/testsuite/27_io/istream_extractor_arith.cc Mon Dec 10 22:06:07 2001
@@ -523,7 +523,7 @@
   int digits_overflow;
   if (integer_type)
     // This many digits will overflow integer types in base 10.
-    digits_overflow = std::numeric_limits<T>::digits10 + 1;
+    digits_overflow = std::numeric_limits<T>::digits10 + 2;
   else
     // This might do it, unsure.
     digits_overflow = std::numeric_limits<T>::max_exponent10 + 1;
@@ -573,7 +573,7 @@
   // 2
   // quick test for failbit on maximum length extraction.
   int i;
-  int max_digits = numeric_limits<int>::digits10;
+  int max_digits = numeric_limits<int>::digits10 + 1;
   string digits;
   for (int j = 0; j < max_digits; ++j)
     digits += '1';



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