[Clang 10] Fix -Wimplicit-int-float-conversion compilation warnings in WTF
authorHironori.Fujii@sony.com <Hironori.Fujii@sony.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 4 Apr 2020 21:42:23 +0000 (21:42 +0000)
committerHironori.Fujii@sony.com <Hironori.Fujii@sony.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 4 Apr 2020 21:42:23 +0000 (21:42 +0000)
https://bugs.webkit.org/show_bug.cgi?id=209955

Reviewed by Darin Adler.

Clang 10 reports a compilation warning for int to float
conversions losing the precision. The warning is often reported
for code converting a floating point value to an integer value.
For example:

> Optional<int> positive_float_to_int(float f) {
>     if (f > INT_MAX)
>         return nullopt;
>     return static_cast<int>(f);
> }

INT_MAX is implicitly converted float, but float can't keep the
precision of such large value. And, C++ spec doesn't specify
whether it would be rounded up or down. Above code should be
rewritten to:

> Optional<int> positive_float_to_int(float f) {
>     if (f >= pow(2, 31))
>         return nullopt;
>     return static_cast<int>(f);
> }

Instead of using pow, this change added a template variable
maxPlusOne<T>.

* wtf/MathExtras.h:
(powerOfTwo): Added.
(doubleToInteger): Added.
(maxPlusOne): Added.
* wtf/MediaTime.cpp:
(WTF::MediaTime::createWithFloat):
(WTF::MediaTime::createWithDouble):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@259537 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WTF/ChangeLog
Source/WTF/wtf/MathExtras.h
Source/WTF/wtf/MediaTime.cpp

index 82b815b..38a0bcf 100644 (file)
@@ -1,3 +1,43 @@
+2020-04-04  Fujii Hironori  <Hironori.Fujii@sony.com>
+
+        [Clang 10] Fix -Wimplicit-int-float-conversion compilation warnings in WTF
+        https://bugs.webkit.org/show_bug.cgi?id=209955
+
+        Reviewed by Darin Adler.
+
+        Clang 10 reports a compilation warning for int to float
+        conversions losing the precision. The warning is often reported
+        for code converting a floating point value to an integer value.
+        For example:
+
+        > Optional<int> positive_float_to_int(float f) {
+        >     if (f > INT_MAX)
+        >         return nullopt;
+        >     return static_cast<int>(f);
+        > }
+
+        INT_MAX is implicitly converted float, but float can't keep the
+        precision of such large value. And, C++ spec doesn't specify
+        whether it would be rounded up or down. Above code should be
+        rewritten to:
+
+        > Optional<int> positive_float_to_int(float f) {
+        >     if (f >= pow(2, 31))
+        >         return nullopt;
+        >     return static_cast<int>(f);
+        > }
+
+        Instead of using pow, this change added a template variable
+        maxPlusOne<T>.
+
+        * wtf/MathExtras.h:
+        (powerOfTwo): Added.
+        (doubleToInteger): Added.
+        (maxPlusOne): Added.
+        * wtf/MediaTime.cpp:
+        (WTF::MediaTime::createWithFloat):
+        (WTF::MediaTime::createWithDouble):
+
 2020-04-03  David Kilzer  <ddkilzer@apple.com>
 
         [Xcode] Replace ASAN_OTHER_CFLAGS and ASAN_OTHER_CPLUSPLUSFLAGS with $(inherited)
index 8ec8987..7939466 100644 (file)
@@ -391,6 +391,19 @@ inline void decomposeDouble(double number, bool& sign, int32_t& exponent, uint64
         mantissa |= 0x10000000000000ull;
 }
 
+template<typename T> constexpr unsigned countOfBits = sizeof(T) * CHAR_BIT;
+template<typename T> constexpr unsigned countOfMagnitudeBits = countOfBits<T> - std::is_signed_v<T>;
+
+constexpr float powerOfTwo(unsigned e)
+{
+    float p = 1;
+    while (e--)
+        p *= 2;
+    return p;
+}
+
+template<typename T> constexpr float maxPlusOne = powerOfTwo(countOfMagnitudeBits<T>);
+
 // Calculate d % 2^{64}.
 inline void doubleToInteger(double d, unsigned long long& value)
 {
@@ -398,7 +411,7 @@ inline void doubleToInteger(double d, unsigned long long& value)
         value = 0;
     else {
         // -2^{64} < fmodValue < 2^{64}.
-        double fmodValue = fmod(trunc(d), std::numeric_limits<unsigned long long>::max() + 1.0);
+        double fmodValue = fmod(trunc(d), maxPlusOne<unsigned long long>);
         if (fmodValue >= 0) {
             // 0 <= fmodValue < 2^{64}.
             // 0 <= value < 2^{64}. This cast causes no loss.
index 13e0899..9397750 100644 (file)
@@ -95,14 +95,14 @@ MediaTime MediaTime::createWithFloat(float floatTime, uint32_t timeScale)
         return invalidTime();
     if (std::isinf(floatTime))
         return std::signbit(floatTime) ? negativeInfiniteTime() : positiveInfiniteTime();
-    if (floatTime > std::numeric_limits<int64_t>::max())
+    if (floatTime >= maxPlusOne<int64_t>)
         return positiveInfiniteTime();
     if (floatTime < std::numeric_limits<int64_t>::min())
         return negativeInfiniteTime();
     if (!timeScale)
         return std::signbit(floatTime) ? negativeInfiniteTime() : positiveInfiniteTime();
 
-    while (floatTime * timeScale > std::numeric_limits<int64_t>::max())
+    while (floatTime * timeScale >= maxPlusOne<int64_t>)
         timeScale /= 2;
     return MediaTime(static_cast<int64_t>(floatTime * timeScale), timeScale, Valid);
 }
@@ -125,14 +125,14 @@ MediaTime MediaTime::createWithDouble(double doubleTime, uint32_t timeScale)
         return invalidTime();
     if (std::isinf(doubleTime))
         return std::signbit(doubleTime) ? negativeInfiniteTime() : positiveInfiniteTime();
-    if (doubleTime > std::numeric_limits<int64_t>::max())
+    if (doubleTime >= maxPlusOne<int64_t>)
         return positiveInfiniteTime();
     if (doubleTime < std::numeric_limits<int64_t>::min())
         return negativeInfiniteTime();
     if (!timeScale)
         return std::signbit(doubleTime) ? negativeInfiniteTime() : positiveInfiniteTime();
 
-    while (doubleTime * timeScale > std::numeric_limits<int64_t>::max())
+    while (doubleTime * timeScale >= maxPlusOne<int64_t>)
         timeScale /= 2;
     return MediaTime(static_cast<int64_t>(std::round(doubleTime * timeScale)), timeScale, Valid);
 }