Add patch for addressing a Boost.Multiprecision bug
This change addresses the issue of https://github.com/boostorg/multiprecision/issues/553, the fix prevents an application from crash due to an exception thrown in a function marked `noexcept`, when converting a `cpp_int` to a float, if the value of this `cpp_int` cannot be represented with a float. this issue is a regression in Boost 1.79, see more details at https://github.com/boostorg/multiprecision/pull/618 Signed-off-by: Kefu Chai <tchaikov@gmail.com>
This commit is contained in:
parent
932a39a687
commit
dce3f3406f
2 changed files with 86 additions and 1 deletions
78
boost-1.83-multiprecision-convert-noexcept.patch
Normal file
78
boost-1.83-multiprecision-convert-noexcept.patch
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
From ea786494db78efdf178cbe36810f3326156e3347 Mon Sep 17 00:00:00 2001
|
||||
From: Kefu Chai <tchaikov@gmail.com>
|
||||
Date: Fri, 3 May 2024 15:08:05 +0800
|
||||
Subject: [PATCH] make sure eval_convert_to() do not terminate with super large
|
||||
number
|
||||
|
||||
this change is a follow-up of d51f2e9dbb. it intends to
|
||||
address the exception thrown in a noexcept functon.
|
||||
|
||||
a minimal reproducer looks like
|
||||
|
||||
```c++
|
||||
|
||||
int main() {
|
||||
std::string s = "32767456456456456456545678943512357658768763546575675";
|
||||
boost::multiprecision::cpp_int num(s);
|
||||
std::cout << num.convert_to<float>() << std::endl;
|
||||
}
|
||||
```
|
||||
|
||||
since boost 1.79, the code above terminates like
|
||||
```
|
||||
Program returned: 139
|
||||
Program stderr
|
||||
terminate called after throwing an instance of 'boost::wrapexcept<std::domain_error>'
|
||||
what(): Error in function float_next<float>(float): Argument must be finite, but got inf
|
||||
Program terminated with signal: SIGSEGV
|
||||
```
|
||||
|
||||
because `float_next_imp()` throws 'boost::wrapexcept<std::domain_error>'
|
||||
if the number is NAN of INF. and `eval_convert_to()` is marked as
|
||||
`noexcept(boost::multiprecision::detail::is_arithmetic<R>::value &&
|
||||
std::numeric_limits<R>::has_infinity)`,
|
||||
but only `overflow_error` is ignored in the policy passed to
|
||||
`float_next()`.
|
||||
|
||||
so, in this change, `std::domain_error` is ignored as well, so that
|
||||
``num.convert_to<float>()` returns a NaN in this case.
|
||||
|
||||
Refs #553
|
||||
|
||||
Signed-off-by: Kefu Chai <tchaikov@gmail.com>
|
||||
---
|
||||
include/boost/multiprecision/cpp_int/misc.hpp | 9 ++++++---
|
||||
1 file changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/include/boost/multiprecision/cpp_int/misc.hpp b/include/boost/multiprecision/cpp_int/misc.hpp
|
||||
index cdae2f75..a8a76400 100644
|
||||
--- a/boost/multiprecision/cpp_int/misc.hpp
|
||||
+++ b/boost/multiprecision/cpp_int/misc.hpp
|
||||
@@ -184,7 +184,9 @@ eval_convert_to(R* result, const cpp_int_backend<MinBits1, MaxBits1, SignType1,
|
||||
|
||||
template <class R, std::size_t MinBits1, std::size_t MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
|
||||
inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<std::is_floating_point<R>::value && !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value, void>::type
|
||||
-eval_convert_to(R* result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& backend) noexcept(boost::multiprecision::detail::is_arithmetic<R>::value && std::numeric_limits<R>::has_infinity)
|
||||
+eval_convert_to(R* result, const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& backend) noexcept(boost::multiprecision::detail::is_arithmetic<R>::value &&
|
||||
+ (std::numeric_limits<R>::has_infinity ||
|
||||
+ std::numeric_limits<R>::has_quiet_NaN))
|
||||
{
|
||||
BOOST_MP_FLOAT128_USING using std::ldexp;
|
||||
if (eval_is_zero(backend))
|
||||
@@ -244,10 +246,11 @@ eval_convert_to(R* result, const cpp_int_backend<MinBits1, MaxBits1, SignType1,
|
||||
if ((eval_lsb_imp(backend) < static_cast<std::size_t>(bits)) || eval_bit_test(backend, static_cast<std::size_t>(bits + 1)))
|
||||
{
|
||||
#ifdef BOOST_MP_MATH_AVAILABLE
|
||||
- BOOST_IF_CONSTEXPR(std::numeric_limits<R>::has_infinity)
|
||||
+ BOOST_IF_CONSTEXPR(std::numeric_limits<R>::has_infinity || std::numeric_limits<R>::has_quiet_NaN)
|
||||
{
|
||||
// Must NOT throw:
|
||||
- *result = boost::math::float_next(*result, boost::math::policies::make_policy(boost::math::policies::overflow_error<boost::math::policies::ignore_error>()));
|
||||
+ *result = boost::math::float_next(*result, boost::math::policies::make_policy(boost::math::policies::overflow_error<boost::math::policies::ignore_error>(),
|
||||
+ boost::math::policies::domain_error<boost::math::policies::ignore_error>()));
|
||||
}
|
||||
else
|
||||
{
|
||||
--
|
||||
2.44.0
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ Name: boost
|
|||
%global real_name boost
|
||||
Summary: The free peer-reviewed portable C++ source libraries
|
||||
Version: 1.83.0
|
||||
Release: 3%{?dist}
|
||||
Release: 4%{?dist}
|
||||
License: BSL-1.0 AND MIT AND Python-2.0.1
|
||||
|
||||
# Replace each . with _ in %%{version}
|
||||
|
|
@ -162,6 +162,9 @@ Patch7: boost-1.81.0-random-test-fixes.patch
|
|||
|
||||
Patch8: boost-1.83-regex-test-fixes.patch
|
||||
|
||||
# https://github.com/boostorg/multiprecision/commit/ea786494db78efdf178cbe36810f3326156e3347
|
||||
Patch9: boost-1.83-multiprecision-convert-noexcept.patch
|
||||
|
||||
%bcond_with tests
|
||||
%bcond_with docs_generated
|
||||
|
||||
|
|
@ -1291,6 +1294,10 @@ fi
|
|||
%{_mandir}/man1/b2.1*
|
||||
|
||||
%changelog
|
||||
* Sun May 05 2024 Kefu Chai <tchaikov@fedoraproject.org> - 1.83.0-4
|
||||
- Add patch for Boost.Multiprecision bug
|
||||
See https://github.com/boostorg/multiprecision/pull/618
|
||||
|
||||
* Wed Jan 31 2024 Pete Walter <pwalter@fedoraproject.org> - 1.83.0-3
|
||||
- Rebuild for ICU 74
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue