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] *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>



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