This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[PATCH] *Much* better one for libstdc++/4402
- From: Paolo Carlini <pcarlini at unitus dot it>
- To: libstdc++ at gcc dot gnu dot org, bkoz at redhat dot com
- Cc: stuart at personalrobots dot com
- Date: Thu, 15 Nov 2001 00:07:18 +0100
- Subject: [PATCH] *Much* better one for libstdc++/4402
Hi again Benjamin, hi all...
once more, a slow progress toward a fully satisfying solution... I beg your pardon.
Today, perusing std_limits.h, I realized that, even for 128 bit long doubles,
max_exponent10 is only 4932: this prompted me to find a simpler, faster (one less
comparison), and not less clear fix.
Therefore, please consider the following patch, tested and checked as usual on
i686-pc-linux-gnu, as my current (and final :-) proposal for PR4402 (Changelog and
testsuite patch remains the same, but, for completeness, I'm including them again)
Thanks for your patience,
Paolo.
.................................
Paolo Carlini <pcarlini@unitus.it>
libstdc++/4402
* testsuite/27_io/ostream_inserter_arith.cc: testcase from the PR.
* include/bits/locale_facets.tcc (num_put::do_put(doubles, long doubles))
Dealing with big std::fixed floats, avoid __sbuf overruns, robustify.
*** ostream_inserter_arith.cc.orig Sun Nov 11 13:48:59 2001
--- ostream_inserter_arith.cc Sun Nov 11 15:13:47 2001
*************** test02()
*** 272,277 ****
--- 272,293 ----
#endif
VERIFY(os && os.str() == largebuf);
+ // make sure we can output a long float in std::fixed format
+ // without seg-faulting (libstdc++/4402)
+ double val2 = 3.5e230;
+
+ ostringstream os2;
+ os2.precision(3);
+ os2.setf(ios::fixed);
+ os2 << val2;
+
+ sprintf(largebuf, "%.*f", 3, val2);
+ #ifdef TEST_NUMPUT_VERBOSE
+ cout << "expect: " << largebuf << endl;
+ cout << "result: " << os2.str() << endl;
+ #endif
+ VERIFY(os2 && os2.str() == largebuf);
+
return 0;
}
*** locale_facets.tcc.orig Sat Nov 10 19:29:38 2001
--- locale_facets.tcc Wed Nov 14 23:21:08 2001
*************** namespace std
*** 875,891 ****
// Protect against sprintf() buffer overflows.
if (__prec > __max_prec)
__prec = __max_prec;
- // The *2 provides for signs, exp, 'E', and pad.
- char __sbuf[__max_prec * 2];
size_t __slen;
// Long enough for the max format spec.
char __fbuf[16];
! if (__build_float_format(__io, __fbuf, 0, __prec))
! __slen = sprintf(__sbuf, __fbuf, __prec, __v);
else
! __slen = sprintf(__sbuf, __fbuf, __v);
! // [22.2.2.2.2] Stages 2-4.
! return __output_float(__s, __io, __fill, __sbuf, __slen);
}
template<typename _CharT, typename _OutIter>
--- 875,909 ----
// Protect against sprintf() buffer overflows.
if (__prec > __max_prec)
__prec = __max_prec;
size_t __slen;
// Long enough for the max format spec.
char __fbuf[16];
! bool __ff = __build_float_format(__io, __fbuf, 0, __prec);
! if (!(__io.flags() & ios_base::fixed) || (__v > -1e35 && __v < 1e35))
! {
! // non-std::fixed and short std::fixed numbers
! char __sbuf[__max_prec * 4];
! if (__ff)
! __slen = sprintf(__sbuf, __fbuf, __prec, __v);
! else
! __slen = sprintf(__sbuf, __fbuf, __v);
! // [22.2.2.2.2] Stages 2-4.
! return __output_float(__s, __io, __fill, __sbuf, __slen);
! }
else
! {
! // long std::fixed numbers
! char* __sbuf =
! new char[numeric_limits<double>::max_exponent10 + __max_prec + 3];
! if (__ff)
! __slen = sprintf(__sbuf, __fbuf, __prec, __v);
! else
! __slen = sprintf(__sbuf, __fbuf, __v);
! // [22.2.2.2.2] Stages 2-4.
! _OutIter __ri = __output_float(__s, __io, __fill, __sbuf, __slen);
! delete[] __sbuf;
! return __ri;
! }
}
template<typename _CharT, typename _OutIter>
*************** namespace std
*** 899,916 ****
// Protect against sprintf() buffer overflows.
if (__prec > __max_prec)
__prec = __max_prec;
- // The *2 provides for signs, exp, 'E', and pad.
- char __sbuf[__max_prec * 2];
size_t __slen;
// Long enough for the max format spec.
char __fbuf[16];
// 'L' as per [22.2.2.2.2] Table 59
! if (__build_float_format(__io, __fbuf, 'L', __prec))
! __slen = sprintf(__sbuf, __fbuf, __prec, __v);
else
! __slen = sprintf(__sbuf, __fbuf, __v);
! // [22.2.2.2.2] Stages 2-4
! return __output_float(__s, __io, __fill, __sbuf, __slen);
}
template<typename _CharT, typename _OutIter>
--- 917,950 ----
// Protect against sprintf() buffer overflows.
if (__prec > __max_prec)
__prec = __max_prec;
size_t __slen;
// Long enough for the max format spec.
char __fbuf[16];
// 'L' as per [22.2.2.2.2] Table 59
! bool __ff = __build_float_format(__io, __fbuf, 'L', __prec);
! if (!(__io.flags() & ios_base::fixed) || (__v > -1e35 && __v < 1e35))
! {
! char __sbuf[__max_prec * 4];
! if (__ff)
! __slen = sprintf(__sbuf, __fbuf, __prec, __v);
! else
! __slen = sprintf(__sbuf, __fbuf, __v);
! // [22.2.2.2.2] Stages 2-4.
! return __output_float(__s, __io, __fill, __sbuf, __slen);
! }
else
! {
! char* __sbuf =
! new char[numeric_limits<long double>::max_exponent10 + __max_prec + 3];
! if (__ff)
! __slen = sprintf(__sbuf, __fbuf, __prec, __v);
! else
! __slen = sprintf(__sbuf, __fbuf, __v);
! // [22.2.2.2.2] Stages 2-4.
! _OutIter __ri = __output_float(__s, __io, __fill, __sbuf, __slen);
! delete[] __sbuf;
! return __ri;
! }
}
template<typename _CharT, typename _OutIter>