fmtlib / fmt

A modern formatting library
https://fmt.dev
Other
20.86k stars 2.51k forks source link

fmt::vformat() throws an exception on Android x86 during chrono formatting. #4244

Open TheStormN opened 3 days ago

TheStormN commented 3 days ago

Hello,

I believe I've discovered a bug in latest version of fmt when compiled using Clang in 32bit x86 mode. We have a legacy codebase with some Time functions wrappers which we try to refactor by using more modern tooling. We use fmt as polyfill for platforms which still don't have proper std:;format() support.

The current issue is reproducible only on our Android x86 pipeline, on all other mobile and desktop platforms the code works as expected. The exception being thrown is fmt::v11::format_error. I've managed to strip down the code to a small reproducible example. Here's the CompilerExplorer link: https://godbolt.org/z/v1Mezdd8T

The moment you remove the -m32 flag the program executes successfully.

#include <chrono>
#include <iostream>

#include <cassert>

#include <fmt/format.h>
#include <fmt/chrono.h>

template <class Clock, class Duration = typename Clock::duration>
std::string formatTime(const std::string& format, const std::chrono::time_point<Clock, Duration>& time)
{
    return fmt::vformat("{:" + format + '}', fmt::make_format_args(time));
}

std::string fromUnixEpochToRFC1123(const int64_t epoch)
{
    std::chrono::system_clock::time_point timePoint{ std::chrono::seconds(epoch / 1000) };

    return formatTime("%a, %d %b %Y %H:%M:%S GMT", std::chrono::floor<std::chrono::seconds>(timePoint));
}

int main() {
    auto result = fromUnixEpochToRFC1123(32536850400000);
    bool isResultExpected = result == "Mon, 19 Jan 3001 22:00:00 GMT";
    assert(isResultExpected);
    std::cout << result << std::endl;
}