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]

[PATCH] Fix libstdc++/5045 (take2)


Hi all, hi Benjamin,

Philip noticed, correctly IMO, that numeric_limits<>::digits10 is apparently used in the
various num_get::do_get for integral types assuming the meaning "max number of digits" vs
"Number of base 10 digits that can be represented without change". Therefore, 1 should be
added to it in each of the corresponding _M_extract_int calls.

I'm currently testing the following patch. Commenting on the previous version of it Nathan
recommended to go ahead and commit, but I would still like to have Gaby ok. What do you
think now?

In my opinion the patch is quite safe, only the testcase does not convince me completely,
based as is on some implementation-dependent #defines. Perhaps it can wait?!?

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/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 Mon Dec 10 21:03:05 2001
@@ -455,8 +455,12 @@
       // 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.
       _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 +486,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 +513,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;
@@ -536,7 +540,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;
@@ -563,7 +567,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;
@@ -589,7 +593,7 @@
       char __xtrc[32];
       int __base;
       _M_extract_int(__beg, __end, __io, __err, __xtrc,
-       numeric_limits<unsigned long long>::digits10, __base);
+       numeric_limits<unsigned long long>::digits10 + 1, __base);

       // Stage 2: convert and store results.
       char* __sanity;
@@ -718,7 +722,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 20:49:01 2001
+++ libstdc++-v3/include/bits/std_limits.h Sat Dec  8 10:04:04 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>();





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