STL icon indicating copy to clipboard operation
STL copied to clipboard

<locale>: wrong field extraction for hexfloats, or special cases like inf

Open fsb4000 opened this issue 5 years ago • 4 comments

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

fsb4000 avatar Sep 03 '20 08:09 fsb4000

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

fsb4000 avatar Sep 03 '20 14:09 fsb4000

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.

frederick-vs-ja avatar Apr 06 '22 07:04 frederick-vs-ja

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

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.

CaseyCarter avatar Apr 07 '22 23:04 CaseyCarter

~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.

frederick-vs-ja avatar Feb 08 '23 03:02 frederick-vs-ja

LLVM-77948 is merged. I guess this issue can be closed by the next LLVM submodule update.

frederick-vs-ja avatar May 22 '24 02:05 frederick-vs-ja

Thanks, I'll pick that up and see what happens.

StephanTLavavej avatar May 22 '24 04:05 StephanTLavavej

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:

StephanTLavavej avatar Jul 17 '24 20:07 StephanTLavavej