Skip to content

chrono locale format code has some bug when using RHEL gcc on CentOS 7.6 to compile #3858

Description

@g199209

Test version : 10.2.1

Test code snippet:

std::locale::global(loc);
auto sat = fmt::weekday(6);
fmt::format(loc, "{:L}", sat);

The code above will throw std::bad_cast when using specifed compiler and OS.

Compiler: g++ (GCC) 12.2.1 20221121 (Red Hat 12.2.1-4)
OS: CentOS 7.6

This gcc is from RHEL Dev tool set 12: https://access.redhat.com/documentation/en-us/red_hat_developer_toolset/12


Root cause: This compile has predefined #define _GLIBCXX_USE_DUAL_ABI 0, the old CentOS 7.6 do not support dual ABI, but the _GLIBCXX_USE_DUAL_ABI IS defined to 0, not undefined.

And related code in include/fmt/chrono.h:

template <typename OutputIt>
auto write_encoded_tm_str(OutputIt out, string_view in, const std::locale& loc)
    -> OutputIt {
  if (detail::is_utf8() && loc != get_classic_locale()) {
    // char16_t and char32_t codecvts are broken in MSVC (linkage errors) and
    // gcc-4.
#if FMT_MSC_VERSION != 0 || \
    (defined(__GLIBCXX__) && !defined(_GLIBCXX_USE_DUAL_ABI))
    // The _GLIBCXX_USE_DUAL_ABI macro is always defined in libstdc++ from gcc-5
    // and newer.
    using code_unit = wchar_t;
#else
    using code_unit = char32_t;
#endif

    using unit_t = codecvt_result<code_unit>;
    unit_t unit;
    write_codecvt(unit, in, loc);
    // ......
}

If _GLIBCXX_USE_DUAL_ABI IS defined, std::use_facet<std::codecvt<char32_t, char, std::mbstate_t>>(loc) will be called in write_codecvt(), which throw std::bad_cast. If I only keep using code_unit = wchar_t; here, the code above can work well.

I think we should not only check whether _GLIBCXX_USE_DUAL_ABI is defined, but also check it's value here:

#if FMT_MSC_VERSION != 0 || \
    (defined(__GLIBCXX__) && (!defined(_GLIBCXX_USE_DUAL_ABI) || _GLIBCXX_USE_DUAL_ABI == 0 ))

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions