Message ID | 20141008100747.GV4197@redhat.com |
---|---|
State | New |
Headers | show |
On 08/10/14 11:07 +0100, Jonathan Wakely wrote: >On 07/10/14 21:10 +0200, Andreas Schwab wrote: >>That cannot work. std::__convert_from_v always passes __prec before >>__v, but the format is "%a". > >Ah yes. I'm testing this fix now. Committed. I assume it was working for me because __convert_from_v("%a", 6, 272.) happens to pass the double differently from the integer, and vsnprintf looks for a double in the relevant register and ignores the integer argument. >commit 543771e2db1642715854ae4bec81d803ca8e2e59 >Author: Jonathan Wakely <jwakely@redhat.com> >Date: Wed Oct 8 10:39:27 2014 +0100 > > * include/bits/locale_facets.tcc (num_put::_M_insert_float): Do not > pass precision when using hexfloat format. > * src/c++98/locale_facets.cc (__num_base::_S_format_float): Always > output precision if C99 hexfloat conversion specifiers not available. > >diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc >index cf12a08..88adc0d 100644 >--- a/libstdc++-v3/include/bits/locale_facets.tcc >+++ b/libstdc++-v3/include/bits/locale_facets.tcc >@@ -988,20 +988,32 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL > __num_base::_S_format_float(__io, __fbuf, __mod); > > #ifdef _GLIBCXX_USE_C99 >+ // Precision is always used except for hexfloat format. >+ const bool __use_prec = >+ (__io.flags() & ios_base::floatfield) != ios_base::floatfield; >+ > // First try a buffer perhaps big enough (most probably sufficient > // for non-ios_base::fixed outputs) > int __cs_size = __max_digits * 3; > char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); >- __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, >- __fbuf, __prec, __v); >+ if (__use_prec) >+ __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, >+ __fbuf, __prec, __v); >+ else >+ __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, >+ __fbuf, __v); > > // If the buffer was not large enough, try again with the correct size. > if (__len >= __cs_size) > { > __cs_size = __len + 1; > __cs = static_cast<char*>(__builtin_alloca(__cs_size)); >- __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, >- __fbuf, __prec, __v); >+ if (__use_prec) >+ __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, >+ __fbuf, __prec, __v); >+ else >+ __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, >+ __fbuf, __v); > } > #else > // Consider the possibility of long ios_base::fixed outputs >diff --git a/libstdc++-v3/src/c++98/locale_facets.cc b/libstdc++-v3/src/c++98/locale_facets.cc >index 7ed04e6..b3ca5dc 100644 >--- a/libstdc++-v3/src/c++98/locale_facets.cc >+++ b/libstdc++-v3/src/c++98/locale_facets.cc >@@ -71,7 +71,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > ios_base::fmtflags __fltfield = __flags & ios_base::floatfield; > >+#ifdef _GLIBCXX_USE_C99 >+ // Precision is always used except for hexfloat format. > if (__fltfield != (ios_base::fixed | ios_base::scientific)) >+#endif > { > // As per DR 231: not only when __flags & ios_base::fixed || __prec > 0 > *__fptr++ = '.';
commit 543771e2db1642715854ae4bec81d803ca8e2e59 Author: Jonathan Wakely <jwakely@redhat.com> Date: Wed Oct 8 10:39:27 2014 +0100 * include/bits/locale_facets.tcc (num_put::_M_insert_float): Do not pass precision when using hexfloat format. * src/c++98/locale_facets.cc (__num_base::_S_format_float): Always output precision if C99 hexfloat conversion specifiers not available. diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc index cf12a08..88adc0d 100644 --- a/libstdc++-v3/include/bits/locale_facets.tcc +++ b/libstdc++-v3/include/bits/locale_facets.tcc @@ -988,20 +988,32 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL __num_base::_S_format_float(__io, __fbuf, __mod); #ifdef _GLIBCXX_USE_C99 + // Precision is always used except for hexfloat format. + const bool __use_prec = + (__io.flags() & ios_base::floatfield) != ios_base::floatfield; + // First try a buffer perhaps big enough (most probably sufficient // for non-ios_base::fixed outputs) int __cs_size = __max_digits * 3; char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); - __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, - __fbuf, __prec, __v); + if (__use_prec) + __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, + __fbuf, __prec, __v); + else + __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, + __fbuf, __v); // If the buffer was not large enough, try again with the correct size. if (__len >= __cs_size) { __cs_size = __len + 1; __cs = static_cast<char*>(__builtin_alloca(__cs_size)); - __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, - __fbuf, __prec, __v); + if (__use_prec) + __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, + __fbuf, __prec, __v); + else + __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, + __fbuf, __v); } #else // Consider the possibility of long ios_base::fixed outputs diff --git a/libstdc++-v3/src/c++98/locale_facets.cc b/libstdc++-v3/src/c++98/locale_facets.cc index 7ed04e6..b3ca5dc 100644 --- a/libstdc++-v3/src/c++98/locale_facets.cc +++ b/libstdc++-v3/src/c++98/locale_facets.cc @@ -71,7 +71,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ios_base::fmtflags __fltfield = __flags & ios_base::floatfield; +#ifdef _GLIBCXX_USE_C99 + // Precision is always used except for hexfloat format. if (__fltfield != (ios_base::fixed | ios_base::scientific)) +#endif { // As per DR 231: not only when __flags & ios_base::fixed || __prec > 0 *__fptr++ = '.';