Skip to content

: Fix formatting for unusual durations - #3649

Merged
Stephan T. Lavavej (StephanTLavavej) merged 11 commits into
microsoft:mainfrom
frederick-vs-ja:duration-fmt-fix
Apr 28, 2023
Merged

Stephan T. Lavavej (StephanTLavavej) merged 11 commits into
microsoft:mainfrom
frederick-vs-ja:duration-fmt-fix

Conversation

@frederick-vs-ja

@frederick-vs-ja A. Jiang (frederick-vs-ja) commented Apr 11, 2023 •

Copy link
Copy Markdown
Contributor

Fixes #3644. hh_mm_ss<_Duration> seems wrong for _Hh_mm_ss_part_underflow_to_zero to me.

Need to explore how to accept duration>. Currently libstdc++ rejects it, while libc++ accepts it (Godbolt link).

Edit: the current approach for calculation of hh_mm_ss::fractional_width doesn't seem right. I'm trying to fix it.

Edit 2: now the formatting is made well-formed, but UB may happen.

@frederick-vs-ja
A. Jiang (frederick-vs-ja) requested a review from a team as a code owner April 11, 2023 04:16
@StephanTLavavej Stephan T. Lavavej (StephanTLavavej) added bug Something isn't working format C++20/23 format chrono C++20 chrono labels Apr 11, 2023
@StephanTLavavej

This comment was marked as resolved.

@frederick-vs-ja

A. Jiang (frederick-vs-ja) commented Apr 12, 2023 •

Copy link
Copy Markdown
Contributor Author

Currently no implementation correctly formats duration>{40} (Godbolt link). In MSVC STL, libc++, and libstdc++, hh_mm_ss is used when formatting duration and thus duration_cast is also involved. And it's extremely easy for duration_cast to cause UB when the source type is duration>.

However, it seems that [time.format] doesn't say duration_cast or hh_mm_ss is equivalently used when formatting duration, so perhaps the current standard wording is requiring correctly formatting such duration...

Comment thread stl/inc/chrono
Comment thread stl/inc/chrono
@strega-nil-ms

nicole mazzuca (strega-nil-ms) commented Apr 12, 2023 •

Copy link
Copy Markdown
Contributor

Wait, actually, I'm trying to understand the UB here... could you write up an example?

@frederick-vs-ja

A. Jiang (frederick-vs-ja) commented Apr 13, 2023 •

Copy link
Copy Markdown
Contributor Author

Wait, actually, I'm trying to understand the UB here... could you write up an example?

I attempted to test formatting duration>{40}. The duration needs to undergo _Hh_mm_ss_part_underflow_to_zero, and thus _Remove_duration_part. Finally duration_cast(...) needs to be called, and signed integer overflow is unavoidable.

Reduced example that contains needed runtime operations and fails to compile due to integer overflow (Godbolt link):

#include <chrono>
#include <cstdint>
#include <limits>
#include <ratio>
#include <type_traits>

using LongRatio = std::ratio<INT64_MAX - 1, INT64_MAX>;
using D = std::chrono::duration<int, LongRatio>;

constexpr auto weird40 = D{40};
constexpr auto cast_to_day = std::chrono::duration_cast(weird40);

hh_mm_ss conversion doesn't work either (Godbolt link).

@strega-nil-ms

This comment was marked as resolved.

@frederick-vs-ja

This comment was marked as resolved.

@StephanTLavavej

Copy link
Copy Markdown
Member

Thanks! I pushed a conflict-free merge with main and trivial header inclusions for the test.

@StephanTLavavej

Copy link
Copy Markdown
Member

I'm mirroring this to the MSVC-internal repo - please notify me if any further changes are pushed.

@StephanTLavavej

Copy link
Copy Markdown
Member

We forgot to defend _STD max against macroization - pushed.

@StephanTLavavej
Stephan T. Lavavej (StephanTLavavej) merged commit bb1798f into microsoft:main Apr 28, 2023
@StephanTLavavej

Copy link
Copy Markdown
Member

Thanks for investigating and fixing this bug! ⌚ 🎉 😸

@frederick-vs-ja
A. Jiang (frederick-vs-ja) deleted the duration-fmt-fix branch April 28, 2023 23:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working chrono C++20 chrono format C++20/23 format

Projects

None yet

Development

Successfully merging this pull request may close these issues.

: Some (weird) durations still cannot be formatted

3 participants