[libcxx] r176711 - Parsing floating point numbers with very long precision was broken, and this patch fixes it. This fixes http://llvm.org/bugs/show_bug.cgi?id=15445.
Howard Hinnant
hhinnant at apple.com
Fri Mar 8 11:06:24 PST 2013
Author: hhinnant
Date: Fri Mar 8 13:06:24 2013
New Revision: 176711
URL: http://llvm.org/viewvc/llvm-project?rev=176711&view=rev
Log:
Parsing floating point numbers with very long precision was broken, and this patch fixes it. This fixes http://llvm.org/bugs/show_bug.cgi?id=15445.
Modified:
libcxx/trunk/include/locale
libcxx/trunk/test/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_double.pass.cpp
Modified: libcxx/trunk/include/locale
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/locale?rev=176711&r1=176710&r2=176711&view=diff
==============================================================================
--- libcxx/trunk/include/locale (original)
+++ libcxx/trunk/include/locale Fri Mar 8 13:06:24 2013
@@ -646,6 +646,8 @@ __num_get<_CharT>::__stage2_float_loop(_
_CharT __decimal_point, _CharT __thousands_sep, const string& __grouping,
unsigned* __g, unsigned*& __g_end, unsigned& __dc, _CharT* __atoms)
{
+ if (__a_end-__a >= __num_get_buf_sz - 1)
+ return -1;
if (__ct == __decimal_point)
{
if (!__in_units)
@@ -673,23 +675,27 @@ __num_get<_CharT>::__stage2_float_loop(_
char __x = __src[__f];
if (__x == '-' || __x == '+')
{
- if (__a_end == __a || (__a_end[-1] & 0xDF) == __exp)
+ if (__a_end == __a || (__a_end[-1] & 0x5F) == (__exp & 0x7F))
{
*__a_end++ = __x;
return 0;
}
return -1;
}
- if (__a_end-__a < __num_get_buf_sz - 1)
- *__a_end++ = __x;
if (__x == 'x' || __x == 'X')
__exp = 'P';
- else if ((__x & 0xDF) == __exp)
+ else if ((__x & 0x5F) == __exp)
{
- __in_units = false;
- if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz)
- *__g_end++ = __dc;
+ __exp |= 0x80;
+ if (__in_units)
+ {
+ __in_units = false;
+ if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz)
+ *__g_end++ = __dc;
+ }
}
+ if (__a_end-__a < __num_get_buf_sz - ((__exp & 0x80) ? 1 : 11))
+ *__a_end++ = __x;
if (__f >= 22)
return 0;
++__dc;
Modified: libcxx/trunk/test/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_double.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_double.pass.cpp?rev=176711&r1=176710&r2=176711&view=diff
==============================================================================
--- libcxx/trunk/test/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_double.pass.cpp (original)
+++ libcxx/trunk/test/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_double.pass.cpp Fri Mar 8 13:06:24 2013
@@ -240,4 +240,16 @@ int main()
assert(iter.base() == str+sizeof(str)-1);
assert(err == ios.failbit);
}
+ {
+ v = -1;
+ const char str[] = "3;14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651e+10";
+ std::ios_base::iostate err = ios.goodbit;
+ input_iterator<const char*> iter =
+ f.get(input_iterator<const char*>(str),
+ input_iterator<const char*>(str+sizeof(str)),
+ ios, err, v);
+ assert(iter.base() == str+sizeof(str)-1);
+ assert(err == ios.goodbit);
+ assert(std::abs(v - 3.14159265358979e+10)/3.14159265358979e+10 < 1.e-8);
+ }
}
More information about the cfe-commits
mailing list