Skip to content

[libc++] long double function call relies on double function #62282

Closed
@JoseLuis-SolidSands

Description

@JoseLuis-SolidSands

In line 745 of file libcxx/include/cmath the following function template is defined:

template <class _Tp> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp __constexpr_scalbn(_Tp __x, int __exp)

This function can be called with a value of type long double as the first argument (e.g., line 710 of file libcxx/include/complex). However, its return statement is:

return __builtin_scalbn(__x, __exp);

This other built-in function takes a double as the first argument (instead of a long double) and also returns a double (instead of a long double). This accuracy loss yields undesired results, as it can be seen in the following example (Compiler Explorer):

#include <complex>

int main( ){
    bool res = true;

    const std::complex<long double> &a = {0.L, 0.5L};
    const std::complex<long double> &b = {0.L, 0.549306144334054845697622618461262852323745278911374725867L};

    std::complex<long double> x = std::atan<>( a );

    res &= ( std::real<long double>(x) == std::real<long double>(b) );
    res &= ( std::imag<long double>(x) == std::imag<long double>(b) );

    return !res;
}

This bug was found in clang 16.0.0 using the SuperTest suite, clang 15.0.0 still works fine.
Compilation flags: -m64 -std=c++20 -stdlib=libc++ -O0 -funsigned-char
Replacing the call to __builtin_scalbn() with a call to __builtin_scalbnl() for this case should fix it (or creating a specialization).

Metadata

Metadata

Assignees

No one assigned

    Labels

    libc++libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.regression

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions