From 057fa3bf4175465bbba3e0919c9e6440955579c3 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 8 Jun 2024 04:50:33 -0700 Subject: [PATCH 1/9] Always `break` at the end of a `switch`. Also remove an unnecessary, inconsistent comment. --- stl/inc/xlocmon | 5 ++++- stl/inc/xloctime | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/stl/inc/xlocmon b/stl/inc/xlocmon index c40f3a4ab8c..0bfca362741 100644 --- a/stl/inc/xlocmon +++ b/stl/inc/xlocmon @@ -567,7 +567,9 @@ private: if (_Pattern.field[_Off] == money_base::space && !_Seen) { _Bad = true; // fail if no space seen } - } // parse optional space + + break; + } } // switch } @@ -840,6 +842,7 @@ private: _Dest = _Rep(_Dest, _Fill, _Fillcount); _Fillcount = 0; } + break; } } diff --git a/stl/inc/xloctime b/stl/inc/xloctime index a0fd7f336c7..52da0f5bae9 100644 --- a/stl/inc/xloctime +++ b/stl/inc/xloctime @@ -563,6 +563,7 @@ protected: default: _State |= ios_base::failbit; // unknown specifier + break; } if (_First == _Last) { From 224f95f815fed1731c4d50c10305c4c6dd1c43bd Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 8 Jun 2024 04:55:03 -0700 Subject: [PATCH 2/9] Add test coverage for warning C26818 "Switch statement does not cover all cases." --- tests/std/rulesets/stl.ruleset | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/std/rulesets/stl.ruleset b/tests/std/rulesets/stl.ruleset index 7859a44da86..d75eee85b0b 100644 --- a/tests/std/rulesets/stl.ruleset +++ b/tests/std/rulesets/stl.ruleset @@ -7,5 +7,7 @@ + + From 882a13a91601629fdcd3f4ebdae67e41c15a9792 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 8 Jun 2024 05:01:03 -0700 Subject: [PATCH 3/9] ``: Fix `money_base::pattern` warnings. These are all covered by the test. Cite the Standard to explain how we've handled all valid values. --- stl/inc/xlocmon | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/stl/inc/xlocmon b/stl/inc/xlocmon index 0bfca362741..3c7d924644f 100644 --- a/stl/inc/xlocmon +++ b/stl/inc/xlocmon @@ -570,6 +570,12 @@ private: break; } + + default: + _STL_ASSERT(false, "Invalid money_base::pattern, see N4981 [locale.moneypunct.general]/1: " + "In the field member of a pattern object, each value symbol, sign, value, " + "and either space or none appears exactly once."); + break; } // switch } @@ -789,6 +795,12 @@ private: } break; + + default: + _STL_ASSERT(false, "Invalid money_base::pattern, see N4981 [locale.moneypunct.general]/1: " + "In the field member of a pattern object, each value symbol, sign, value, " + "and either space or none appears exactly once."); + break; } } @@ -843,6 +855,12 @@ private: _Fillcount = 0; } break; + + default: + _STL_ASSERT(false, "Invalid money_base::pattern, see N4981 [locale.moneypunct.general]/1: " + "In the field member of a pattern object, each value symbol, sign, value, " + "and either space or none appears exactly once."); + break; } } From 54cf227d5d68fef14a7f28fae8d9c86482a84d9d Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 8 Jun 2024 05:08:05 -0700 Subject: [PATCH 4/9] ``: Fix `_Num_bytes` warning. Add a comment to explain why we've handled all cases. --- stl/inc/format | 3 +++ 1 file changed, 3 insertions(+) diff --git a/stl/inc/format b/stl/inc/format index bf507722124..2ab86282a1d 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -292,6 +292,9 @@ _NODISCARD constexpr _Decode_result _Decode_utf(const char* _First, const case 4: _Val &= 0b111u; break; + default: + _STL_INTERNAL_CHECK(false); // can't happen, see how the value of _Num_bytes is determined + break; } for (int _Idx = 1; _Idx < _Num_bytes; ++_Idx) { From 9350b30ae27eec5ac85a86f3288125790f06d499 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 8 Jun 2024 05:15:25 -0700 Subject: [PATCH 5/9] ``: Fix more warnings by adding empty `default: break;`. These are all covered by the test. They're all used, i.e. making them `abort()` causes tests to fail. --- stl/inc/format | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/stl/inc/format b/stl/inc/format index 2ab86282a1d..657e29a96f8 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -276,6 +276,8 @@ _NODISCARD constexpr _Decode_result _Decode_utf(const char* _First, const return {_First + 1, false}; } break; + default: + break; } // mask out the "value bits" in the leading byte, @@ -1261,6 +1263,8 @@ _NODISCARD constexpr const _CharT* _Parse_align( case '^': _Parsed_align = _Fmt_align::_Center; break; + default: + break; } if (_Parsed_align != _Fmt_align::_None) { @@ -2852,6 +2856,8 @@ _NODISCARD _OutputIt _Write_integral( case 'o': _Base = 8; break; + default: + break; } // long long -1 representation in binary is 64 bits + sign From bdf44e779ab672c0e68aa6fa8eee4ad2628239a7 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 8 Jun 2024 05:46:31 -0700 Subject: [PATCH 6/9] Fix `range_formatter` warnings, add test coverage. These are both covered by the new test. The empty `default: break;` is used, i.e. making it `abort()` causes tests to fail. Add a comment to explain why `_Parse_range_specs()` guarantees that the other can't happen. --- stl/inc/format | 6 ++++ .../test.compile.pass.cpp | 33 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/stl/inc/format b/stl/inc/format index 657e29a96f8..8c9d79ce084 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -4456,6 +4456,8 @@ _NODISCARD constexpr const _CharT* _Parse_range_specs( _Callbacks._On_type(_Maybe_type); ++_Begin; break; + default: + break; } return _Begin; @@ -4543,6 +4545,10 @@ public: } break; + + default: + _STL_INTERNAL_CHECK(false); // can't happen, we've handled all possible outputs from _Parse_range_specs() + break; } if (_Specs._No_brackets) { diff --git a/tests/std/tests/GH_002094_cpp_core_guidelines/test.compile.pass.cpp b/tests/std/tests/GH_002094_cpp_core_guidelines/test.compile.pass.cpp index 1132aa12357..ef7428cef76 100644 --- a/tests/std/tests/GH_002094_cpp_core_guidelines/test.compile.pass.cpp +++ b/tests/std/tests/GH_002094_cpp_core_guidelines/test.compile.pass.cpp @@ -2,3 +2,36 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include <__msvc_all_public_headers.hpp> + +using namespace std; + +#if _HAS_CXX23 +template +struct WrappedVector : vector { + using vector::vector; +}; + +template +struct std::formatter, char> { +public: + template + constexpr auto parse(ParseContext& ctx) { + return underlying.parse(ctx); + } + + template + auto format(const WrappedVector& rng, FormatContext& ctx) const { + return underlying.format(rng, ctx); + } + +private: + range_formatter underlying; +}; + +void instantiate_range_formatter_machinery() { + const WrappedVector v{11, 22, 33, 44}; + assert(format("{}", v) == "[11, 22, 33, 44]"); + assert(format("{:}", v) == "[11, 22, 33, 44]"); + assert(format("{:n}", v) == "11, 22, 33, 44"); +} +#endif // ^^^ _HAS_CXX23 ^^^ From 0b293a07177bf6f5f5e10de3eb1906511fa25a77 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 8 Jun 2024 06:13:08 -0700 Subject: [PATCH 7/9] Fix `chrono::parse` warning, add test coverage. This is covered by the new test. The empty `default: break;` is used, i.e. making it `abort()` causes tests to fail. --- stl/inc/chrono | 2 ++ .../GH_002094_cpp_core_guidelines/test.compile.pass.cpp | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/stl/inc/chrono b/stl/inc/chrono index 8b3a2cbd2d4..4a8e089c91a 100644 --- a/stl/inc/chrono +++ b/stl/inc/chrono @@ -4177,6 +4177,8 @@ namespace chrono { case '+': ++_First; break; + default: + break; } // For a regular offset hh[mm], simply read four digits, with the option of an EOF or non-digit after diff --git a/tests/std/tests/GH_002094_cpp_core_guidelines/test.compile.pass.cpp b/tests/std/tests/GH_002094_cpp_core_guidelines/test.compile.pass.cpp index ef7428cef76..51edaec0c96 100644 --- a/tests/std/tests/GH_002094_cpp_core_guidelines/test.compile.pass.cpp +++ b/tests/std/tests/GH_002094_cpp_core_guidelines/test.compile.pass.cpp @@ -5,6 +5,15 @@ using namespace std; +#if _HAS_CXX20 +void instantiate_chrono_parse_machinery() { + istringstream iss{"10:02:07"}; + chrono::seconds s{}; + iss >> chrono::parse("%H:%M:%S", s); + assert(s == 36127s); +} +#endif // ^^^ _HAS_CXX20 ^^^ + #if _HAS_CXX23 template struct WrappedVector : vector { From ff057811801056fedbde0fc6e4f8d9e931077461 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 8 Jun 2024 06:20:06 -0700 Subject: [PATCH 8/9] Fix `regex` warning, add test coverage. This is covered by the new test. The empty `default: break;` is used, i.e. making it `abort()` causes tests to fail. --- stl/inc/regex | 3 +++ .../GH_002094_cpp_core_guidelines/test.compile.pass.cpp | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/stl/inc/regex b/stl/inc/regex index 9061d5b54f9..587c3b60559 100644 --- a/stl/inc/regex +++ b/stl/inc/regex @@ -3922,6 +3922,9 @@ void _Parser<_FwdIt, _Elem, _RxTraits>::_Trans() { // map character to meta-char } break; + + default: + break; } } diff --git a/tests/std/tests/GH_002094_cpp_core_guidelines/test.compile.pass.cpp b/tests/std/tests/GH_002094_cpp_core_guidelines/test.compile.pass.cpp index 51edaec0c96..ac0cb8599fa 100644 --- a/tests/std/tests/GH_002094_cpp_core_guidelines/test.compile.pass.cpp +++ b/tests/std/tests/GH_002094_cpp_core_guidelines/test.compile.pass.cpp @@ -5,6 +5,11 @@ using namespace std; +void instantiate_regex_machinery() { + const regex r{R"(.+meow.+)"}; + assert(regex_match("homeowner", r)); +} + #if _HAS_CXX20 void instantiate_chrono_parse_machinery() { istringstream iss{"10:02:07"}; From 5453bdf732a395fd887952b3f529b23f336787c9 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 13 Jun 2024 07:19:01 -0700 Subject: [PATCH 9/9] Use `_STL_UNREACHABLE`. --- stl/inc/format | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stl/inc/format b/stl/inc/format index 8c9d79ce084..b734cb23b97 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -295,7 +295,7 @@ _NODISCARD constexpr _Decode_result _Decode_utf(const char* _First, const _Val &= 0b111u; break; default: - _STL_INTERNAL_CHECK(false); // can't happen, see how the value of _Num_bytes is determined + _STL_UNREACHABLE; // can't happen, see how the value of _Num_bytes is determined break; } @@ -4547,7 +4547,7 @@ public: break; default: - _STL_INTERNAL_CHECK(false); // can't happen, we've handled all possible outputs from _Parse_range_specs() + _STL_UNREACHABLE; // can't happen, we've handled all possible outputs from _Parse_range_specs() break; }