Kaydet (Commit) b5cb4935 authored tarafından Stephan Bergmann's avatar Stephan Bergmann

Work around undef conversion of large double to float

...as flagged by -fsanitize=undefined.  But is it really undefined?
[conv.double] "If the source value is between two adjacent destination values,
the result of the conversion is an implementation-defined choice of either of
those values."  So if the double is between std::numeric_limits<float>::max()
and std::numeric_limits<float>::infinity()...

Change-Id: I6389c8ac4a922991e240638d231dd2a39e173882
üst 4330085f
......@@ -23,6 +23,7 @@
#include <stdio.h>
#include <algorithm>
#include <limits>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
......@@ -34,6 +35,21 @@
namespace rtl_OUString
{
namespace {
// Avoid -fsanitize=undefined warning e.g. "runtime error: value 1e+99 is
// outside the range of representable values of type 'float'":
float doubleToFloat(double x) {
return
x < -std::numeric_limits<float>::max()
? -std::numeric_limits<float>::infinity()
: x > std::numeric_limits<float>::max()
? std::numeric_limits<float>::infinity()
: static_cast<float>(x);
}
}
class number : public CppUnit::TestFixture
{
void number_float_test_impl(float _nValue)
......@@ -43,7 +59,7 @@ class number : public CppUnit::TestFixture
sValue <<= suValue;
printf("nFloat := %.9f sValue := %s\n", _nValue, sValue.getStr());
float nValueATOF = static_cast<float>(atof( sValue.getStr() ));
double nValueATOF = doubleToFloat(atof( sValue.getStr() ));
bool bEqualResult = is_float_equal(_nValue, nValueATOF);
CPPUNIT_ASSERT_MESSAGE("Values are not equal.", bEqualResult == true);
......@@ -439,7 +455,7 @@ sal_Int16 SAL_CALL checkPrecisionSize()
void toFloat_test_impl(rtl::OString const& _sValue)
{
//printf("the original str is %s\n", _sValue.getStr());
float nValueATOF = static_cast<float>(atof( _sValue.getStr() ));
float nValueATOF = doubleToFloat(atof( _sValue.getStr() ));
//printf("the original str is %.10f\n", nValueATOF);
rtl::OUString suValue = rtl::OUString::createFromAscii( _sValue.getStr() );
float nValueToFloat = suValue.toFloat();
......
......@@ -148,11 +148,26 @@ sal_Int32 SAL_CALL rtl_ustr_valueOfDouble(sal_Unicode * pStr, double d)
return nLen;
}
namespace {
// Avoid -fsanitize=undefined warning e.g. "runtime error: value 1e+99 is
// outside the range of representable values of type 'float'":
float doubleToFloat(double x) {
return
x < -std::numeric_limits<float>::max()
? -std::numeric_limits<float>::infinity()
: x > std::numeric_limits<float>::max()
? std::numeric_limits<float>::infinity()
: static_cast<float>(x);
}
}
float SAL_CALL rtl_ustr_toFloat(sal_Unicode const * pStr) SAL_THROW_EXTERN_C()
{
return (float) rtl_math_uStringToDouble(pStr,
return doubleToFloat(rtl_math_uStringToDouble(pStr,
pStr + rtl_ustr_getLength(pStr),
'.', 0, 0, 0);
'.', 0, 0, 0));
}
double SAL_CALL rtl_ustr_toDouble(sal_Unicode const * pStr) SAL_THROW_EXTERN_C()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment