diff --git a/stl/inc/format b/stl/inc/format index 0b40e3cac1f..738eb9a279c 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -1568,7 +1568,16 @@ private: _Arg_type = _Basic_format_arg_type::_Custom_type; } - _Store_impl<_Erased_type>(_Arg_index, _Arg_type, static_cast<_Erased_type>(_Val)); + if constexpr (is_volatile_v<_Ty>) { + // _Erased_type is not a volatile type, so static_cast<_Erased_type> would cast away volatile + // _Store_impl uses memcpy for storing the value. We cannot use memcpy with volatile types. + // Because of the two reasons we have to make a temporary + static_assert(!is_volatile_v<_Erased_type>); + const _Erased_type _Temp = _Val; + _Store_impl<_Erased_type>(_Arg_index, _Arg_type, _Temp); + } else { + _Store_impl<_Erased_type>(_Arg_index, _Arg_type, static_cast<_Erased_type>(_Val)); + } } public: diff --git a/tests/std/tests/P0645R10_text_formatting_args/test.cpp b/tests/std/tests/P0645R10_text_formatting_args/test.cpp index 494fd95fc1b..b1487ac767a 100644 --- a/tests/std/tests/P0645R10_text_formatting_args/test.cpp +++ b/tests/std/tests/P0645R10_text_formatting_args/test.cpp @@ -217,6 +217,13 @@ void test_visit_monostate() { assert(visit_format_arg(visitor, basic_format_arg()) == Arg_type::none); } +void test_gh_2427() { + // : volatile integral compilation error + volatile int vol = 42; + auto ret = format("{}", vol); + assert(ret == "42"); +} + int main() { test_basic_format_arg(); test_basic_format_arg(); @@ -224,4 +231,6 @@ int main() { test_format_arg_store(); test_visit_monostate(); test_visit_monostate(); + + test_gh_2427(); }