llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.42k stars 12.15k forks source link

[libc++][format] Negation of `LLONG_MIN` (UB) when formatting `chrono::duration` #60123

Open JMazurkiewicz opened 1 year ago

JMazurkiewicz commented 1 year ago

Example:

#include <chrono>
#include <format>
#include <iostream>

using namespace std; 

int main() {
    cout << format("{:%Q}\n", chrono::nanoseconds::min());
}

Expected output:

-9223372036854775808

Got:

--9223372036854775808

Compiler explorer: https://godbolt.org/z/cvcYsTbM8 Similar issue in MSVC STL: https://github.com/microsoft/STL/issues/1902

Comparison with fmtlib: https://godbolt.org/z/YEvPYWKTb

mordante commented 1 year ago

This seems like a bug in the Standard http://www.eelis.net/c++draft/time.format#4

The result of formatting a std​::​chrono​::​duration instance holding a negative value, or an hh_­mm_­ss object h for which h.is_­negative() is true, is equivalent to the output of the corresponding positive value, with a STATICALLY-WIDEN<charT>("-") character sequence placed before the replacement of the initial conversion specifier[.](http://www.eelis.net/c++draft/time.format#4.sentence-1)

There is no corresponding positive value for the minimum value. I'll investigate it later in more detail.

jwakely commented 1 year ago

I think this needs an LWG issue.

FWIW libstdc++ prints the same thing, and also has a UBsan error.