From b5cb4935c268f12e63b61e035b455b0a59e67aa2 Mon Sep 17 00:00:00 2001 From: Stephan Bergmann Date: Thu, 22 May 2014 18:31:07 +0200 Subject: 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::max() and std::numeric_limits::infinity()... Change-Id: I6389c8ac4a922991e240638d231dd2a39e173882 --- sal/rtl/ustring.cxx | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'sal/rtl') diff --git a/sal/rtl/ustring.cxx b/sal/rtl/ustring.cxx index f10e755bbc7b..a79c9177a3ee 100644 --- a/sal/rtl/ustring.cxx +++ b/sal/rtl/ustring.cxx @@ -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::max() + ? -std::numeric_limits::infinity() + : x > std::numeric_limits::max() + ? std::numeric_limits::infinity() + : static_cast(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() -- cgit