From 2b512c716b21d63b97b93adaf12abf652aad5c6a Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Mon, 25 Jul 2022 10:52:19 +0800 Subject: [PATCH 1/5] Zero dynamic width doesn't lead to death (LWG-3721) --- tests/std/tests/P0645R10_text_formatting_death/test.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/std/tests/P0645R10_text_formatting_death/test.cpp b/tests/std/tests/P0645R10_text_formatting_death/test.cpp index e72fab0920f..99b42fda433 100644 --- a/tests/std/tests/P0645R10_text_formatting_death/test.cpp +++ b/tests/std/tests/P0645R10_text_formatting_death/test.cpp @@ -17,17 +17,12 @@ void test_case_advance_no_range() { context.advance_to(other_format_string.begin()); } -void test_case_zero_dynamic_width() { - (void) format("{:{}}", 42, 0); -} - int main(int argc, char* argv[]) { std_testing::death_test_executive exec; #if _ITERATOR_DEBUG_LEVEL != 0 exec.add_death_tests({ test_case_advance_no_range, - test_case_zero_dynamic_width, }); #endif // _ITERATOR_DEBUG_LEVEL != 0 From 76d8a02ad8d8903084e00c40fbdd5f0fc349906a Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Mon, 25 Jul 2022 10:55:46 +0800 Subject: [PATCH 2/5] Test coverage for LWG-3721 --- tests/std/tests/P0645R10_text_formatting_formatting/test.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/std/tests/P0645R10_text_formatting_formatting/test.cpp b/tests/std/tests/P0645R10_text_formatting_formatting/test.cpp index c1835218ad5..f819949870f 100644 --- a/tests/std/tests/P0645R10_text_formatting_formatting/test.cpp +++ b/tests/std/tests/P0645R10_text_formatting_formatting/test.cpp @@ -1287,6 +1287,8 @@ void libfmt_formatter_test_runtime_width() { == STR(" 0")); // behavior differs from libfmt, but conforms throw_helper(STR("{0:{1}}"), 0, 0.0); + assert(format(STR("{0:{1}}"), 42, 0) == STR("42")); // LWG-3721: zero dynamic width is OK + assert(format(STR("{0:{1}}"), -42, 4) == STR(" -42")); assert(format(STR("{0:{1}}"), 42u, 5) == STR(" 42")); assert(format(STR("{0:{1}}"), -42l, 6) == STR(" -42")); From 3e66d6a465e210aee12e709aac68886be8e25607 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Mon, 25 Jul 2022 11:07:49 +0800 Subject: [PATCH 3/5] Implement LWG-3721 --- stl/inc/format | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/stl/inc/format b/stl/inc/format index 3e89553d827..4ab9f5d950b 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -1421,15 +1421,15 @@ public: template _NODISCARD constexpr unsigned long long operator()(const _Ty _Value) const { if constexpr (is_integral_v<_Ty>) { - bool _Positive; - if constexpr (same_as<_Ty, bool>) { // avoid "bool > 0", which triggers C4804 - _Positive = _Value != 0; + bool _Negative; + if constexpr (same_as<_Ty, bool>) { // avoid "bool < 0", which triggers C4804 + _Negative = false; } else { - _Positive = _Value > 0; + _Negative = _Value < 0; } - if (!_Positive) { - _Throw_format_error("width is not positive."); + if (_Negative) { + _Throw_format_error("width is negative."); } return static_cast(_Value); } else { From edf4c390a8415aeb1cf4562a9923863f991c09d1 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Mon, 25 Jul 2022 11:19:35 +0800 Subject: [PATCH 4/5] Consistency improvements --- stl/inc/format | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/stl/inc/format b/stl/inc/format index 4ab9f5d950b..24e45376e2b 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -1421,15 +1421,10 @@ public: template _NODISCARD constexpr unsigned long long operator()(const _Ty _Value) const { if constexpr (is_integral_v<_Ty>) { - bool _Negative; - if constexpr (same_as<_Ty, bool>) { // avoid "bool < 0", which triggers C4804 - _Negative = false; - } else { - _Negative = _Value < 0; - } - - if (_Negative) { - _Throw_format_error("width is negative."); + if constexpr (is_signed_v<_Ty>) { + if (_Value < 0) { + _Throw_format_error("Negative width."); + } } return static_cast(_Value); } else { From 50677c0e63d0a8c424156aef07f0e4c4aa84b6f3 Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Tue, 26 Jul 2022 19:01:56 -0700 Subject: [PATCH 5/5] Add failure test for negative dynamic width --- tests/std/tests/P0645R10_text_formatting_death/test.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/std/tests/P0645R10_text_formatting_death/test.cpp b/tests/std/tests/P0645R10_text_formatting_death/test.cpp index 99b42fda433..e09eba9dc28 100644 --- a/tests/std/tests/P0645R10_text_formatting_death/test.cpp +++ b/tests/std/tests/P0645R10_text_formatting_death/test.cpp @@ -17,12 +17,17 @@ void test_case_advance_no_range() { context.advance_to(other_format_string.begin()); } +void test_case_negative_dynamic_width() { + (void) format("{:{}}", 42, -2); +} + int main(int argc, char* argv[]) { std_testing::death_test_executive exec; #if _ITERATOR_DEBUG_LEVEL != 0 exec.add_death_tests({ test_case_advance_no_range, + test_case_negative_dynamic_width, }); #endif // _ITERATOR_DEBUG_LEVEL != 0