Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<format>: compile time checks #2221

Merged
merged 25 commits into from
Dec 17, 2021

Conversation

barcharcraz
Copy link
Member

@barcharcraz barcharcraz commented Sep 27, 2021

This is the second half of P2216R3 (the first half is already implemented), and continues @vitaut's work from #1882

There's no new tests accompanying this PR because we don't really have "tests that should not compile". I did mess remove the throw_helper call from around several of the tests in P0645R10_text_formatting_formatting to verify those invalid strings failed to compile.

The compile time format string checking is disabled if we can't figure out that you're using a utf-8 execution character set at compile time. The compiler does have a new feature that lets us find out about other character sets, but in addition to that we'd need constexpr decoding for GB18030/GBK and CP932 (or any other legacy codepages that don't self-synchronize, or move format control characters around). This PR does enforce that the format string must be a compile-time constant, even for those unsupported codepages.

Fixes #1981.

@barcharcraz barcharcraz requested a review from a team as a code owner September 27, 2021 22:54
@StephanTLavavej StephanTLavavej added cxx20 C++20 feature defect report Applied retroactively format C++20/23 format labels Sep 27, 2021
@StephanTLavavej

This comment has been minimized.

Copy link
Contributor

@miscco miscco left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor nints about naming, but looks great overall

stl/inc/format Show resolved Hide resolved
stl/inc/format Outdated Show resolved Hide resolved
stl/inc/format Outdated Show resolved Hide resolved
stl/inc/format Outdated Show resolved Hide resolved
stl/inc/format Outdated Show resolved Hide resolved
stl/inc/format Outdated Show resolved Hide resolved
stl/inc/format Outdated Show resolved Hide resolved
stl/inc/format Show resolved Hide resolved
stl/inc/format Show resolved Hide resolved
tests/std/tests/P0645R10_text_formatting_utf8/test.cpp Outdated Show resolved Hide resolved
stl/inc/format Show resolved Hide resolved
Copy link
Member

@CaseyCarter CaseyCarter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Partial review.

We fail to reject even the motivating example from the paper (std::format("{:d}", "I am not a number")), because we perform most specs validation in the writer functions (which aren't called at compile time) for builtin types. Am I missing something here?

stl/inc/chrono Outdated Show resolved Hide resolved
stl/inc/chrono Outdated Show resolved Hide resolved
stl/inc/format Outdated Show resolved Hide resolved
stl/inc/format Outdated Show resolved Hide resolved
stl/inc/format Outdated Show resolved Hide resolved
stl/inc/format Show resolved Hide resolved
stl/inc/format Outdated Show resolved Hide resolved
stl/inc/format Outdated Show resolved Hide resolved
@@ -979,9 +991,9 @@ void test_spec_replacement_field() {
test_pointer_specs<charT>();
test_string_specs<charT>();
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style nitpick: The newline between these functions should be retained. (The general convention is to have a newline between all functions, except for short highly repetitive functions.) However, this isn't worth resetting testing.

@@ -1269,7 +1270,7 @@
#define __cpp_lib_erase_if 202002L

#if _HAS_CXX23 && defined(__cpp_lib_concepts) // TRANSITION, GH-395 and GH-1814
#define __cpp_lib_format 201907L
#define __cpp_lib_format 202106L // P2216R3 std::format improvements
Copy link
Member

@CaseyCarter CaseyCarter Nov 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We only have a comment like this for macros that are defined to different values in different cases - __cpp_lib_format is all-or-nothing. (Not worth resetting testing if we touch nothing else.)

@@ -665,6 +667,7 @@ void test_char_specs() {
// Precision
throw_helper(STR("{:.5}"), charT{'X'});


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's the extra line that was removed from right before 994. =)

test_size_helper_impl<wchar_t, Args...>(expected_size, fmt, forward<Args>(args)...);
}


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto "extraneous newline to remove if we need to touch something else."

stl/inc/format Show resolved Hide resolved
@CaseyCarter CaseyCarter removed their assignment Dec 15, 2021
@StephanTLavavej StephanTLavavej self-assigned this Dec 16, 2021
@StephanTLavavej
Copy link
Member

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

@StephanTLavavej
Copy link
Member

I've pushed a workaround for an ICE in the internal "chk" compiler build. Introducing a named variable _Iter avoids the ICE.

@StephanTLavavej StephanTLavavej merged commit 9265c51 into microsoft:main Dec 17, 2021
@StephanTLavavej
Copy link
Member

Thanks for implementing this major C++20 DR! 😸 🎉 ✅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cxx20 C++20 feature defect report Applied retroactively format C++20/23 format
Projects
None yet
Development

Successfully merging this pull request may close these issues.

P2216R3 std::format Improvements
5 participants