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.

Reply via email to