https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123991
Jonathan Wakely <redi at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Known to fail| |13.4.0, 14.3.0, 15.2.0,
| |16.0, 7.3.0, 8.1.0
Summary|std::string::compare |[13/14/15/16 Regression]
|crashes instead of throwing |std::string::compare
| |crashes instead of throwing
Known to work| |7.2.0
--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
The noexcept was added by r8-2892-gdf66af3b1edaf4
The same conditional noexcept was added here:
+ template<typename _Tp>
+ _If_sv<_Tp, int>
+ compare(const _Tp& __svt) const
+ noexcept(is_same<_Tp, __sv_type>::value)
+ {
And in this case it's correct. As the standard says:
-?- Throws: Nothing unless the initialization of sv throws an exception.
So when _Tp is already string_view, we know that initializing a string_view
from __svt will not throw.
But for the topic of this bug report:
+ template<typename _Tp>
+ _If_sv<_Tp, int>
+ compare(size_type __pos, size_type __n, const _Tp& __svt) const
+ noexcept(is_same<_Tp, __sv_type>::value)
+ {
+ __sv_type __sv = __svt;
+ return __sv_type(*this).substr(__pos, __n).compare(__sv);
+ }
Adding the conditional noexcept was wrong, because the substr can throw even if
initializing __sv cannot throw.
This is a regression, because GCC 7.2.0 was correct (and then I backported the
gcc-8 change to the gcc-7 branch as bb85d61e6bfba).
The same problem exists on this overload:
template<typename _Tp>
_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
_If_sv<_Tp, int>
compare(size_type __pos1, size_type __n1, const _Tp& __svt,
size_type __pos2, size_type __n2 = npos) const
noexcept(is_same<_Tp, __sv_type>::value)
{
__sv_type __sv = __svt;
return __sv_type(*this)
.substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
}