<locale>: wrong field extraction for hexfloats, or special cases like inf
Describe the bug We don't match strtod / strtof when doing field extraction for hexfloats, or special cases like inf
Command-line test case
C:\Temp>type main.cpp
#include <cassert>
#include <cmath>
#include <sstream>
template<typename Float>
void test()
{
{
const char str[] = "0x125p-1 ";
std::stringstream f(str);
Float v;
f >> v;
assert (v == 0x125p-1);
assert (f.good());
}
{
const char str[] = "inf ";
std::stringstream f(str);
Float v;
f >> v;
assert (v == INFINITY);
assert (f.good());
}
{
const char str[] = "INF ";
std::stringstream f(str);
Float v;
f >> v;
assert (v == INFINITY);
assert (f.good());
}
{
const char str[] = "-inf ";
std::stringstream f(str);
Float v;
f >> v;
assert (v == -INFINITY);
assert (f.good());
}
{
const char str[] = "-INF ";
std::stringstream f(str);
Float v;
f >> v;
assert (v == -INFINITY);
assert (f.good());
}
{
const char str[] = "nan ";
std::stringstream f(str);
Float v;
f >> v;
assert (std::isnan(v));
assert (f.good());
}
{
const char str[] = "NAN ";
std::stringstream f(str);
Float v;
f >> v;
assert (std::isnan(v));
assert (f.good());
}
}
int main()
{
test<float>();
test<double>();
test<long double>();
{
const char str[] = "3.40283e+39 "; // unrepresentable
std::stringstream f(str);
float v;
f >> v;
assert (v == HUGE_VAL);
assert (f.fail());
}
{
const char str[] = "-3.40283e+38 "; // unrepresentable
std::stringstream f(str);
float v;
f >> v;
assert (v == -HUGE_VAL);
assert (f.fail());
}
{
const char str[] = "1.79779e+309 "; // unrepresentable
std::stringstream f(str);
double v;
f >> v;
assert (v == HUGE_VAL);
assert (f.fail());
}
{
const char str[] = "-1.79779e+308 "; // unrepresentable
std::stringstream f(str);
double v;
f >> v;
assert (v == -HUGE_VAL);
assert (f.fail());
}
{
const char str[] = "1.19973e+4933 "; // unrepresentable
std::stringstream f(str);
long double v;
f >> v;
assert (v == HUGE_VAL);
assert (f.fail());
}
{
const char str[] = "-1.18974e+4932 "; // unrepresentable
std::stringstream f(str);
long double v;
f >> v;
assert (v == -HUGE_VAL);
assert (f.fail());
}
}
C:\Temp>cl /EHsc /W4 /WX /std:c++17 main.cpp
Оптимизирующий компилятор Microsoft (R) C/C++ версии 19.28.29213 для x64
(C) Корпорация Майкрософт (Microsoft Corporation). Все права защищены.
main.cpp
Microsoft (R) Incremental Linker Version 14.28.29213.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:main.exe
main.obj
C:\Temp>main
Assertion failed: v == 0x125p-1, file main.cpp, line 13
Expected behavior All tests should pass.
STL version
Microsoft Visual Studio Community 2019 Preview Version 16.8.0 Preview 2.0
Additional context Skipped libcxx test https://github.com/microsoft/STL/blob/06827feb4cdc4d2328dfbfab9fd5302de6058dd9/tests/libcxx/expected_results.txt#L591-L594
std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long_double.pass.cpp FAIL
most likely it will fail even after fixing this bug, since MSVC long double = double and there are tests with large values that do not fit into double.
std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_double.pass.cpp FAIL
and
std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_float.pass.cpp FAIL
should work
Maybe a duplicate of LWG-2381/#2388.
Unfortunately the libcxx tests shouldn't be enabled at this moment, as "inf" and "nan" are intendedly not supported in the resolution of LWG-2381.
std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_long_double.pass.cpp FAILmost likely it will fail even after fixing this bug, since MSVC long double = double and there are tests with large values that do not fit into double.
std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_double.pass.cpp FAILandstd/localization/locale.categories/category.numeric/locale.num.get/facet.num.get.members/get_float.pass.cpp FAILshould work
It's not unusual for us to fix the cause for skipping a libc++ test only to immediately list it as skipped for another reason. IIRC we even have tests that appear more than once in the skip lists when there are multiple known reasons for failure.
~I've reported LLVM-60597.~ (It shouldn't be reported again.) I think this is no longer a bug of MSVC STL (but of libc++) after implementing LWG-2381 in STL.
LLVM-77948 is merged. I guess this issue can be closed by the next LLVM submodule update.
Thanks, I'll pick that up and see what happens.
As @frederick-vs-ja mentioned in Discord, we can close this now. The STL has been fixed with #3364 (further patched by #3982) and the LLVM submodule has been updated by #4702 to enable the affected tests. Thanks everyone! :heart_eyes_cat: