https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94353
Bug ID: 94353 Summary: std::copy* breaks when one type is volatile Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: alex at grundis dot de Target Milestone: --- The following code breaks: #include <algorithm> void foo(const char* b, volatile char* d){ std::copy_n(b, 10, d); } This is a regression from earlier versions where it worked fine. The reason is that at some point `struct __copy_move<_IsMove, true, random_access_iterator_tag>::__copy_m(const _Tp* __first, const _Tp* __last, _Tp* __result)` is called where it fails to deduce `__Tp` because it is `char` and `volatile char` Full stack: In file included from /usr/local/include/c++/10.0.1/bits/char_traits.h:39, from /usr/local/include/c++/10.0.1/string:40, from /usr/local/include/c++/10.0.1/stdexcept:39, from /usr/local/include/c++/10.0.1/system_error:41, from /home/jakecooke/Code/CPP/Glade/src/simulator/abseil-cpp/absl/strings/charconv.h:18, from /home/jakecooke/Code/CPP/Glade/src/simulator/abseil-cpp/absl/strings/charconv.cc:15: /usr/local/include/c++/10.0.1/bits/stl_algobase.h: In instantiation of 'constexpr _OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false; _II = const char*; _OI = volatile char*]': /usr/local/include/c++/10.0.1/bits/stl_algobase.h:533:42: required from 'constexpr _OI std::__copy_move_a1(_II, _II, _OI) [with bool _IsMove = false; _II = const char*; _OI = volatile char*]' /usr/local/include/c++/10.0.1/bits/stl_algobase.h:541:31: required from 'constexpr _OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false; _II = const char*; _OI = volatile char*]' /usr/local/include/c++/10.0.1/bits/stl_algobase.h:596:7: required from 'constexpr _OI std::copy(_II, _II, _OI) [with _II = const char*; _OI = volatile char*]' /usr/local/include/c++/10.0.1/bits/stl_algo.h:820:23: required from 'constexpr _OutputIterator std::__copy_n(_RandomAccessIterator, _Size, _OutputIterator, std::random_access_iterator_tag) [with _RandomAccessIterator = const char*; _Size = long int; _OutputIterator = volatile char*]' /usr/local/include/c++/10.0.1/bits/stl_algo.h:847:27: required from 'constexpr _OIter std::copy_n(_IIter, _Size, _OIter) [with _IIter = const char*; _Size = long int; _OIter = volatile char*]' /home/jakecooke/Code/CPP/Glade/src/simulator/abseil-cpp/absl/strings/charconv.cc:301:7: required from 'bool absl::{anonymous}::HandleEdgeCase(const absl::strings_internal::ParsedFloat&, bool, FloatType*) [with FloatType = double]' /home/jakecooke/Code/CPP/Glade/src/simulator/abseil-cpp/absl/strings/charconv.cc:636:23: required from 'absl::from_chars_result absl::{anonymous}::FromCharsImpl(const char*, const char*, FloatType&, absl::chars_format) [with FloatType = double]' /home/jakecooke/Code/CPP/Glade/src/simulator/abseil-cpp/absl/strings/charconv.cc:681:47: required from here /usr/local/include/c++/10.0.1/bits/stl_algobase.h:499:30: error: no matching function for call to 'std::__copy_move<false, true, std::random_access_iterator_tag>::__copy_m(const char*&, const char*&, volatile char*&)' 498 | return std::__copy_move<_IsMove, __simple, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 499 | _Category>::__copy_m(__first, __last, __result); | ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~ /usr/local/include/c++/10.0.1/bits/stl_algobase.h:441:2: note: candidate: 'template<class _Tp> static constexpr _Tp* std::__copy_move<_IsMove, true, std::random_access_iterator_tag>::__copy_m(const _Tp*, const _Tp*, _Tp*) [with _Tp = _Tp; bool _IsMove = false]' 441 | __copy_m(const _Tp* __first, const _Tp* __last, _Tp* __result) | ^~~~~~~~ /usr/local/include/c++/10.0.1/bits/stl_algobase.h:441:2: note: template argument deduction/substitution failed: /usr/local/include/c++/10.0.1/bits/stl_algobase.h:499:30: note: deduced conflicting types for parameter '_Tp' ('char' and 'volatile char') 498 | return std::__copy_move<_IsMove, __simple, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 499 | _Category>::__copy_m(__first, __last, __result); | ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~ It seems that this should be fixed by https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=462f6c2041fad058abcdd5122e99a024f69a39d5 because `__memcpyable<volatile char*, const char*>` should return false. But there doesn't seem to be a test case for mixed volatile pointers. I'd suggest to add them