Title: [185755] trunk
Revision
185755
Author
mark....@apple.com
Date
2015-06-19 10:46:02 -0700 (Fri, 19 Jun 2015)

Log Message

CheckedArithmetic's operator bool() and operator==() is broken.
https://bugs.webkit.org/show_bug.cgi?id=146129

Reviewed by Geoffrey Garen and Oliver Hunt.

Source/WTF:

The existing operator UnspecifiedBoolType*() in CheckedArithmetic is erroneously
allowing the Checked value to be implicitly casted into pointer types.  This is
because it is doing a reinterpret_cast<UnspecifiedBoolType*>(1) whereas the idiom
relies on the address of a member e.g. &Checked::m_value.  As a result,
ImageBufferData::putData() was getting an implicit cast of a Checked value to
(void*)1 and doing incorrect pointer comparisons on it.

Also, 2 of CheckedArithmetic's operator==() will crash if used on an overflowed
value, while a 3rd one does not.  The 3rd one should be consistent and also crash
if used on an overflowed Checked value.

In this fix, we replace operator UnspecifiedBoolType*() with an explicit operator
bool().  We also add the missing operators <, <=, >, and >=.  That takes care of
the comparisons in ImageBufferData::putData().

* wtf/CheckedArithmetic.h:
(WTF::CrashOnOverflow::overflowed):
(WTF::CrashOnOverflow::crash):
(WTF::RecordOverflow::crash):

(WTF::Checked::operator!):
(WTF::Checked::operator bool):
(WTF::Checked::unsafeGet):
- Don't call CRASH() directly.  Delegate to the handler.

(WTF::Checked::operator==):
- Should call the handler's crash() to be consistent with the other 2 versions of
  operator== which will crash in unsafeGet() if used on an overflowed Checked
  value.

(WTF::Checked::operator<):
(WTF::Checked::operator<=):
(WTF::Checked::operator>):
(WTF::Checked::operator>=):
- Add missing operators.

(WTF::Checked::operator UnspecifiedBoolType*): Deleted.

Tools:

Added API tests for operator ==, !=, <, <=, >, and >=, and tested for both normal
and overflow scenarios in usage of the Checked arithmetic class.

* TestWebKitAPI/Tests/WTF/CheckedArithmeticOperations.cpp:
(TestWebKitAPI::OverflowCrashLogger::overflowed):
(TestWebKitAPI::OverflowCrashLogger::clearOverflow):
(TestWebKitAPI::OverflowCrashLogger::crash):
(TestWebKitAPI::OverflowCrashLogger::reset):
(TestWebKitAPI::OverflowCrashLogger::hasOverflowed):
(TestWebKitAPI::OverflowCrashLogger::overflowCount):
(TestWebKitAPI::OverflowCrashLogger::didCrash):
- crash logger for verifying that a crash occurs when expected. 

(TestWebKitAPI::resetOverflow):
- convenience function for resetting a test value to an initial overflowed state
  before a crash.  We will use this value in the overflow testing.

(TestWebKitAPI::CheckedArithmeticTester::run):
- Added new tests for all the comparison operators.

Modified Paths

Diff

Modified: trunk/Source/WTF/ChangeLog (185754 => 185755)


--- trunk/Source/WTF/ChangeLog	2015-06-19 17:38:24 UTC (rev 185754)
+++ trunk/Source/WTF/ChangeLog	2015-06-19 17:46:02 UTC (rev 185755)
@@ -1,3 +1,48 @@
+2015-06-19  Mark Lam  <mark....@apple.com>
+
+        CheckedArithmetic's operator bool() and operator==() is broken.
+        https://bugs.webkit.org/show_bug.cgi?id=146129
+
+        Reviewed by Geoffrey Garen and Oliver Hunt.
+
+        The existing operator UnspecifiedBoolType*() in CheckedArithmetic is erroneously
+        allowing the Checked value to be implicitly casted into pointer types.  This is
+        because it is doing a reinterpret_cast<UnspecifiedBoolType*>(1) whereas the idiom
+        relies on the address of a member e.g. &Checked::m_value.  As a result,
+        ImageBufferData::putData() was getting an implicit cast of a Checked value to
+        (void*)1 and doing incorrect pointer comparisons on it.
+
+        Also, 2 of CheckedArithmetic's operator==() will crash if used on an overflowed
+        value, while a 3rd one does not.  The 3rd one should be consistent and also crash
+        if used on an overflowed Checked value.
+
+        In this fix, we replace operator UnspecifiedBoolType*() with an explicit operator
+        bool().  We also add the missing operators <, <=, >, and >=.  That takes care of
+        the comparisons in ImageBufferData::putData().
+
+        * wtf/CheckedArithmetic.h:
+        (WTF::CrashOnOverflow::overflowed):
+        (WTF::CrashOnOverflow::crash):
+        (WTF::RecordOverflow::crash):
+
+        (WTF::Checked::operator!):
+        (WTF::Checked::operator bool):
+        (WTF::Checked::unsafeGet):
+        - Don't call CRASH() directly.  Delegate to the handler.
+
+        (WTF::Checked::operator==):
+        - Should call the handler's crash() to be consistent with the other 2 versions of
+          operator== which will crash in unsafeGet() if used on an overflowed Checked
+          value.
+
+        (WTF::Checked::operator<):
+        (WTF::Checked::operator<=):
+        (WTF::Checked::operator>):
+        (WTF::Checked::operator>=):
+        - Add missing operators.
+
+        (WTF::Checked::operator UnspecifiedBoolType*): Deleted.
+
 2015-06-19  Csaba Osztrogonác  <o...@webkit.org>
 
         [WK2] Fix unused-private-field warning in WebProcess/Plugins/PluginView.<h|cpp>

Modified: trunk/Source/WTF/wtf/CheckedArithmetic.h (185754 => 185755)


--- trunk/Source/WTF/wtf/CheckedArithmetic.h	2015-06-19 17:38:24 UTC (rev 185754)
+++ trunk/Source/WTF/wtf/CheckedArithmetic.h	2015-06-19 17:46:02 UTC (rev 185755)
@@ -75,11 +75,16 @@
 public:
     static NO_RETURN_DUE_TO_CRASH void overflowed()
     {
-        CRASH();
+        crash();
     }
 
     void clearOverflow() { }
 
+    static NO_RETURN_DUE_TO_CRASH void crash()
+    {
+        CRASH();
+    }
+
 public:
     bool hasOverflowed() const { return false; }
 };
@@ -101,6 +106,11 @@
         m_overflowed = false;
     }
 
+    static NO_RETURN_DUE_TO_CRASH void crash()
+    {
+        CRASH();
+    }
+
 public:
     bool hasOverflowed() const { return m_overflowed; }
 
@@ -517,23 +527,22 @@
     bool operator!() const
     {
         if (this->hasOverflowed())
-            CRASH();
+            this->crash();
         return !m_value;
     }
 
-    typedef void* (Checked::*UnspecifiedBoolType);
-    operator UnspecifiedBoolType*() const
+    explicit operator bool() const
     {
         if (this->hasOverflowed())
-            CRASH();
-        return (m_value) ? reinterpret_cast<UnspecifiedBoolType*>(1) : 0;
+            this->crash();
+        return m_value;
     }
 
     // Value accessors. unsafeGet() will crash if there's been an overflow.
     T unsafeGet() const
     {
         if (this->hasOverflowed())
-            CRASH();
+            this->crash();
         return m_value;
     }
     
@@ -612,7 +621,7 @@
     template <typename U> bool operator==(U rhs)
     {
         if (this->hasOverflowed())
-            this->overflowed();
+            this->crash();
         return safeEquals(m_value, rhs);
     }
     
@@ -626,6 +635,47 @@
         return !(*this == rhs);
     }
 
+    // Other comparisons
+    template <typename V> bool operator<(Checked<T, V> rhs) const
+    {
+        return unsafeGet() < rhs.unsafeGet();
+    }
+
+    template bool operator<(T rhs) const
+    {
+        return unsafeGet() < rhs;
+    }
+
+    template <typename V> bool operator<=(Checked<T, V> rhs) const
+    {
+        return unsafeGet() <= rhs.unsafeGet();
+    }
+
+    template bool operator<=(T rhs) const
+    {
+        return unsafeGet() <= rhs;
+    }
+
+    template <typename V> bool operator>(Checked<T, V> rhs) const
+    {
+        return unsafeGet() > rhs.unsafeGet();
+    }
+
+    template bool operator>(T rhs) const
+    {
+        return unsafeGet() > rhs;
+    }
+
+    template <typename V> bool operator>=(Checked<T, V> rhs) const
+    {
+        return unsafeGet() >= rhs.unsafeGet();
+    }
+
+    template bool operator>=(T rhs) const
+    {
+        return unsafeGet() >= rhs;
+    }
+
 private:
     // Disallow implicit conversion of floating point to integer types
     Checked(float);

Modified: trunk/Tools/ChangeLog (185754 => 185755)


--- trunk/Tools/ChangeLog	2015-06-19 17:38:24 UTC (rev 185754)
+++ trunk/Tools/ChangeLog	2015-06-19 17:46:02 UTC (rev 185755)
@@ -1,3 +1,30 @@
+2015-06-19  Mark Lam  <mark....@apple.com>
+
+        CheckedArithmetic's operator bool() and operator==() is broken.
+        https://bugs.webkit.org/show_bug.cgi?id=146129
+
+        Reviewed by Geoffrey Garen and Oliver Hunt.
+
+        Added API tests for operator ==, !=, <, <=, >, and >=, and tested for both normal
+        and overflow scenarios in usage of the Checked arithmetic class.
+
+        * TestWebKitAPI/Tests/WTF/CheckedArithmeticOperations.cpp:
+        (TestWebKitAPI::OverflowCrashLogger::overflowed):
+        (TestWebKitAPI::OverflowCrashLogger::clearOverflow):
+        (TestWebKitAPI::OverflowCrashLogger::crash):
+        (TestWebKitAPI::OverflowCrashLogger::reset):
+        (TestWebKitAPI::OverflowCrashLogger::hasOverflowed):
+        (TestWebKitAPI::OverflowCrashLogger::overflowCount):
+        (TestWebKitAPI::OverflowCrashLogger::didCrash):
+        - crash logger for verifying that a crash occurs when expected. 
+
+        (TestWebKitAPI::resetOverflow):
+        - convenience function for resetting a test value to an initial overflowed state
+          before a crash.  We will use this value in the overflow testing.
+
+        (TestWebKitAPI::CheckedArithmeticTester::run):
+        - Added new tests for all the comparison operators.
+
 2015-06-19  Per Arne Vollan  <pe...@outlook.com>
 
         Fix the Windows build after r185721

Modified: trunk/Tools/TestWebKitAPI/Tests/WTF/CheckedArithmeticOperations.cpp (185754 => 185755)


--- trunk/Tools/TestWebKitAPI/Tests/WTF/CheckedArithmeticOperations.cpp	2015-06-19 17:38:24 UTC (rev 185754)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/CheckedArithmeticOperations.cpp	2015-06-19 17:46:02 UTC (rev 185755)
@@ -25,9 +25,54 @@
 
 #include "config.h"
 #include <wtf/CheckedArithmetic.h>
+#include <wtf/DataLog.h> // mlam
 
 namespace TestWebKitAPI {
 
+class OverflowCrashLogger {
+protected:
+    void overflowed()
+    {
+        m_overflowCount++;
+    }
+    
+    void clearOverflow()
+    {
+        m_overflowCount = 0;
+    }
+    
+    static void crash()
+    {
+        s_didCrash = true;
+    }
+    
+public:
+    void reset()
+    {
+        m_overflowCount = 0;
+        s_didCrash = false;
+    }
+    
+    bool hasOverflowed() const { return m_overflowCount > 0; }
+    int overflowCount() const { return m_overflowCount; }
+
+    bool didCrash() const { return s_didCrash; }
+    
+private:
+    int m_overflowCount { 0 };
+    static bool s_didCrash;
+};
+
+bool OverflowCrashLogger::s_didCrash = false;
+
+template <typename type>
+static void resetOverflow(Checked<type, OverflowCrashLogger>& value)
+{
+    value.reset();
+    value = 100;
+    value *= std::numeric_limits<type>::max();
+}
+
 #define CheckedArithmeticTest(type, Coercer, MixedSignednessTester) \
     TEST(WTF, Checked_##type) \
     { \
@@ -121,6 +166,201 @@
         value = 10;
         EXPECT_EQ(true, (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).hasOverflowed());
 
+
+        Checked<type, OverflowCrashLogger> nvalue; // to hold a not overflowed value.
+        Checked<type, OverflowCrashLogger> ovalue; // to hold an overflowed value.
+        bool unused;
+
+        _value = 75;
+        type _largeValue = 100;
+        type _smallValue = 50;
+
+        value = _smallValue;
+        nvalue = _value;
+        ovalue = _value;
+
+        // Make sure the OverflowCrashLogger is working as expected.
+        EXPECT_EQ(false, (ovalue.hasOverflowed()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), ovalue.hasOverflowed()));
+        EXPECT_EQ(false, (resetOverflow(ovalue), ovalue.didCrash()));
+        EXPECT_EQ(true, (unused = (ovalue == ovalue), ovalue.didCrash()));
+        EXPECT_EQ(false, (resetOverflow(ovalue), ovalue.didCrash()));
+
+        EXPECT_EQ(false, nvalue.hasOverflowed());
+        EXPECT_EQ(false, nvalue.didCrash());
+
+        // Test operator== that should not overflow nor crash.
+        EXPECT_EQ(true, (nvalue == nvalue));
+        EXPECT_EQ(true, (nvalue == Checked<type, OverflowCrashLogger>(_value)));
+        EXPECT_EQ(false, (nvalue == value));
+        EXPECT_EQ(true, (nvalue == _value));
+        EXPECT_EQ(false, (nvalue == Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())));
+        EXPECT_EQ(false, (nvalue == std::numeric_limits<type>::max()));
+
+        EXPECT_EQ(false, nvalue.hasOverflowed());
+        EXPECT_EQ(false, nvalue.didCrash());
+
+        // Test operator!= that should not overflow nor crash.
+        EXPECT_EQ(false, (nvalue != nvalue));
+        EXPECT_EQ(false, (nvalue != Checked<type, OverflowCrashLogger>(_value)));
+        EXPECT_EQ(true, (nvalue != value));
+        EXPECT_EQ(false, (nvalue != _value));
+        EXPECT_EQ(true, (nvalue != Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())));
+        EXPECT_EQ(true, (nvalue != std::numeric_limits<type>::max()));
+
+        EXPECT_EQ(false, nvalue.hasOverflowed());
+        EXPECT_EQ(false, nvalue.didCrash());
+
+        // Test operator< that should not overflow nor crash.
+        EXPECT_EQ(false, (nvalue < nvalue));
+        EXPECT_EQ(false, (nvalue < value));
+        EXPECT_EQ(true, (nvalue < Checked<type, OverflowCrashLogger>(_largeValue)));
+        EXPECT_EQ(false, (nvalue < Checked<type, OverflowCrashLogger>(_value)));
+        EXPECT_EQ(false, (nvalue < Checked<type, OverflowCrashLogger>(_smallValue)));
+        EXPECT_EQ(true, (nvalue < _largeValue));
+        EXPECT_EQ(false, (nvalue < _value));
+        EXPECT_EQ(false, (nvalue < _smallValue));
+        EXPECT_EQ(true, (nvalue < Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())));
+        EXPECT_EQ(true, (nvalue < std::numeric_limits<type>::max()));
+
+        EXPECT_EQ(false, nvalue.hasOverflowed());
+        EXPECT_EQ(false, nvalue.didCrash());
+
+        // Test operator<= that should not overflow nor crash.
+        EXPECT_EQ(true, (nvalue <= nvalue));
+        EXPECT_EQ(false, (nvalue <= value));
+        EXPECT_EQ(true, (nvalue <= Checked<type, OverflowCrashLogger>(_largeValue)));
+        EXPECT_EQ(true, (nvalue <= Checked<type, OverflowCrashLogger>(_value)));
+        EXPECT_EQ(false, (nvalue <= Checked<type, OverflowCrashLogger>(_smallValue)));
+        EXPECT_EQ(true, (nvalue <= _largeValue));
+        EXPECT_EQ(true, (nvalue <= _value));
+        EXPECT_EQ(false, (nvalue <= _smallValue));
+        EXPECT_EQ(true, (nvalue <= Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())));
+        EXPECT_EQ(true, (nvalue <= std::numeric_limits<type>::max()));
+
+        EXPECT_EQ(false, nvalue.hasOverflowed());
+        EXPECT_EQ(false, nvalue.didCrash());
+
+        // Test operator> that should not overflow nor crash.
+        EXPECT_EQ(false, (nvalue > nvalue));
+        EXPECT_EQ(true, (nvalue > value));
+        EXPECT_EQ(false, (nvalue > Checked<type, OverflowCrashLogger>(_largeValue)));
+        EXPECT_EQ(false, (nvalue > Checked<type, OverflowCrashLogger>(_value)));
+        EXPECT_EQ(true, (nvalue > Checked<type, OverflowCrashLogger>(_smallValue)));
+        EXPECT_EQ(false, (nvalue > _largeValue));
+        EXPECT_EQ(false, (nvalue > _value));
+        EXPECT_EQ(true, (nvalue > _smallValue));
+        EXPECT_EQ(false, (nvalue > Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())));
+        EXPECT_EQ(false, (nvalue > std::numeric_limits<type>::max()));
+
+        EXPECT_EQ(false, nvalue.hasOverflowed());
+        EXPECT_EQ(false, nvalue.didCrash());
+
+        // Test operator>= that should not overflow nor crash.
+        EXPECT_EQ(true, (nvalue >= nvalue));
+        EXPECT_EQ(true, (nvalue >= value));
+        EXPECT_EQ(false, (nvalue >= Checked<type, OverflowCrashLogger>(_largeValue)));
+        EXPECT_EQ(true, (nvalue >= Checked<type, OverflowCrashLogger>(_value)));
+        EXPECT_EQ(true, (nvalue >= Checked<type, OverflowCrashLogger>(_smallValue)));
+        EXPECT_EQ(false, (nvalue >= _largeValue));
+        EXPECT_EQ(true, (nvalue >= _value));
+        EXPECT_EQ(true, (nvalue >= _smallValue));
+        EXPECT_EQ(false, (nvalue >= Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())));
+        EXPECT_EQ(false, (nvalue >= std::numeric_limits<type>::max()));
+
+        EXPECT_EQ(false, nvalue.hasOverflowed());
+        EXPECT_EQ(false, nvalue.didCrash());
+
+        // Test operator== with an overflowed value.
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == ovalue), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == Checked<type, OverflowCrashLogger>(_value)), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == value), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == _value), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == _value * std::numeric_limits<type>::max()), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == std::numeric_limits<type>::max()), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == nvalue), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (nvalue == ovalue), ovalue.didCrash()));
+
+        EXPECT_EQ(false, nvalue.hasOverflowed());
+
+        // Test operator!= with an overflowed value.
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != ovalue), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != Checked<type, OverflowCrashLogger>(_value)), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != value), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != _value), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != _value * std::numeric_limits<type>::max()), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != std::numeric_limits<type>::max()), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != nvalue), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (nvalue != ovalue), ovalue.didCrash()));
+
+        EXPECT_EQ(false, nvalue.hasOverflowed());
+
+        // Test operator< with an overflowed value.
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < ovalue), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < value), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < Checked<type, OverflowCrashLogger>(_largeValue)), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < Checked<type, OverflowCrashLogger>(_value)), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < Checked<type, OverflowCrashLogger>(_smallValue)), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < _largeValue), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < _value), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < _smallValue), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < std::numeric_limits<type>::max()), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < nvalue), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (nvalue < ovalue), ovalue.didCrash()));
+
+        EXPECT_EQ(false, nvalue.hasOverflowed());
+
+        // Test operator<= with an overflowed value.
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= ovalue), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= value), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= Checked<type, OverflowCrashLogger>(_largeValue)), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= Checked<type, OverflowCrashLogger>(_value)), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= Checked<type, OverflowCrashLogger>(_smallValue)), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= _largeValue), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= _value), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= _smallValue), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= std::numeric_limits<type>::max()), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= nvalue), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (nvalue <= ovalue), ovalue.didCrash()));
+
+        EXPECT_EQ(false, nvalue.hasOverflowed());
+
+        // Test operator> with an overflowed value.
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > ovalue), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > value), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > Checked<type, OverflowCrashLogger>(_largeValue)), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > Checked<type, OverflowCrashLogger>(_value)), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > Checked<type, OverflowCrashLogger>(_smallValue)), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > _largeValue), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > _value), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > _smallValue), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > std::numeric_limits<type>::max()), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > nvalue), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (nvalue > ovalue), ovalue.didCrash()));
+
+        EXPECT_EQ(false, nvalue.hasOverflowed());
+
+        // Test operator>= with an overflowed value.
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= ovalue), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= value), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= Checked<type, OverflowCrashLogger>(_largeValue)), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= Checked<type, OverflowCrashLogger>(_value)), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= Checked<type, OverflowCrashLogger>(_smallValue)), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= _largeValue), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= _value), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= _smallValue), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= std::numeric_limits<type>::max()), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= nvalue), ovalue.didCrash()));
+        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (nvalue >= ovalue), ovalue.didCrash()));
+
+        EXPECT_EQ(false, nvalue.hasOverflowed());
+
         MixedSignednessTester::run();
     }
 };
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to