https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108323
Jonathan Wakely <redi at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Last reconfirmed|2024-01-30 00:00:00 |2024-2-1 --- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> --- Kinda related, the implementation of locale::combine uses _M_replace_facet which seems to have a bug: void locale::_Impl:: _M_replace_facet(const _Impl* __imp, const locale::id* __idp) { size_t __index = __idp->_M_id(); if ((__index > (__imp->_M_facets_size - 1)) || !__imp->_M_facets[__index]) __throw_runtime_error(__N("locale::_Impl::_M_replace_facet")); _M_install_facet(__idp, __imp->_M_facets[__index]); } This only checks that a facet with the specified id is present. This is not sufficient, because it could be a different derived type that has the same id. e.g. struct custom_ctype : ctype<char> { ... }; auto loc = std::locale().combine<custom_ctype>(std::locale()); This should throw std::runtime_error because has_facet<custom_ctype> is false. For combine, _M_replace_facet should use std::has_facet as specified in the standard. I haven't checked if that would be correct for the other uses of _M_replace_facet.