Changeset 185755 in webkit


Ignore:
Timestamp:
Jun 19, 2015, 10:46:02 AM (10 years ago)
Author:
mark.lam@apple.com
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.
Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WTF/ChangeLog

    r185742 r185755  
     12015-06-19  Mark Lam  <mark.lam@apple.com>
     2
     3        CheckedArithmetic's operator bool() and operator==() is broken.
     4        https://bugs.webkit.org/show_bug.cgi?id=146129
     5
     6        Reviewed by Geoffrey Garen and Oliver Hunt.
     7
     8        The existing operator UnspecifiedBoolType*() in CheckedArithmetic is erroneously
     9        allowing the Checked value to be implicitly casted into pointer types.  This is
     10        because it is doing a reinterpret_cast<UnspecifiedBoolType*>(1) whereas the idiom
     11        relies on the address of a member e.g. &Checked::m_value.  As a result,
     12        ImageBufferData::putData() was getting an implicit cast of a Checked value to
     13        (void*)1 and doing incorrect pointer comparisons on it.
     14
     15        Also, 2 of CheckedArithmetic's operator==() will crash if used on an overflowed
     16        value, while a 3rd one does not.  The 3rd one should be consistent and also crash
     17        if used on an overflowed Checked value.
     18
     19        In this fix, we replace operator UnspecifiedBoolType*() with an explicit operator
     20        bool().  We also add the missing operators <, <=, >, and >=.  That takes care of
     21        the comparisons in ImageBufferData::putData().
     22
     23        * wtf/CheckedArithmetic.h:
     24        (WTF::CrashOnOverflow::overflowed):
     25        (WTF::CrashOnOverflow::crash):
     26        (WTF::RecordOverflow::crash):
     27
     28        (WTF::Checked::operator!):
     29        (WTF::Checked::operator bool):
     30        (WTF::Checked::unsafeGet):
     31        - Don't call CRASH() directly.  Delegate to the handler.
     32
     33        (WTF::Checked::operator==):
     34        - Should call the handler's crash() to be consistent with the other 2 versions of
     35          operator== which will crash in unsafeGet() if used on an overflowed Checked
     36          value.
     37
     38        (WTF::Checked::operator<):
     39        (WTF::Checked::operator<=):
     40        (WTF::Checked::operator>):
     41        (WTF::Checked::operator>=):
     42        - Add missing operators.
     43
     44        (WTF::Checked::operator UnspecifiedBoolType*): Deleted.
     45
    1462015-06-19  Csaba Osztrogonác  <ossy@webkit.org>
    247
  • trunk/Source/WTF/wtf/CheckedArithmetic.h

    r167548 r185755  
    7676    static NO_RETURN_DUE_TO_CRASH void overflowed()
    7777    {
     78        crash();
     79    }
     80
     81    void clearOverflow() { }
     82
     83    static NO_RETURN_DUE_TO_CRASH void crash()
     84    {
    7885        CRASH();
    7986    }
    80 
    81     void clearOverflow() { }
    8287
    8388public:
     
    100105    {
    101106        m_overflowed = false;
     107    }
     108
     109    static NO_RETURN_DUE_TO_CRASH void crash()
     110    {
     111        CRASH();
    102112    }
    103113
     
    518528    {
    519529        if (this->hasOverflowed())
    520             CRASH();
     530            this->crash();
    521531        return !m_value;
    522532    }
    523533
    524     typedef void* (Checked::*UnspecifiedBoolType);
    525     operator UnspecifiedBoolType*() const
     534    explicit operator bool() const
    526535    {
    527536        if (this->hasOverflowed())
    528             CRASH();
    529         return (m_value) ? reinterpret_cast<UnspecifiedBoolType*>(1) : 0;
     537            this->crash();
     538        return m_value;
    530539    }
    531540
     
    534543    {
    535544        if (this->hasOverflowed())
    536             CRASH();
     545            this->crash();
    537546        return m_value;
    538547    }
     
    613622    {
    614623        if (this->hasOverflowed())
    615             this->overflowed();
     624            this->crash();
    616625        return safeEquals(m_value, rhs);
    617626    }
     
    625634    {
    626635        return !(*this == rhs);
     636    }
     637
     638    // Other comparisons
     639    template <typename V> bool operator<(Checked<T, V> rhs) const
     640    {
     641        return unsafeGet() < rhs.unsafeGet();
     642    }
     643
     644    template bool operator<(T rhs) const
     645    {
     646        return unsafeGet() < rhs;
     647    }
     648
     649    template <typename V> bool operator<=(Checked<T, V> rhs) const
     650    {
     651        return unsafeGet() <= rhs.unsafeGet();
     652    }
     653
     654    template bool operator<=(T rhs) const
     655    {
     656        return unsafeGet() <= rhs;
     657    }
     658
     659    template <typename V> bool operator>(Checked<T, V> rhs) const
     660    {
     661        return unsafeGet() > rhs.unsafeGet();
     662    }
     663
     664    template bool operator>(T rhs) const
     665    {
     666        return unsafeGet() > rhs;
     667    }
     668
     669    template <typename V> bool operator>=(Checked<T, V> rhs) const
     670    {
     671        return unsafeGet() >= rhs.unsafeGet();
     672    }
     673
     674    template bool operator>=(T rhs) const
     675    {
     676        return unsafeGet() >= rhs;
    627677    }
    628678
  • trunk/Tools/ChangeLog

    r185747 r185755  
     12015-06-19  Mark Lam  <mark.lam@apple.com>
     2
     3        CheckedArithmetic's operator bool() and operator==() is broken.
     4        https://bugs.webkit.org/show_bug.cgi?id=146129
     5
     6        Reviewed by Geoffrey Garen and Oliver Hunt.
     7
     8        Added API tests for operator ==, !=, <, <=, >, and >=, and tested for both normal
     9        and overflow scenarios in usage of the Checked arithmetic class.
     10
     11        * TestWebKitAPI/Tests/WTF/CheckedArithmeticOperations.cpp:
     12        (TestWebKitAPI::OverflowCrashLogger::overflowed):
     13        (TestWebKitAPI::OverflowCrashLogger::clearOverflow):
     14        (TestWebKitAPI::OverflowCrashLogger::crash):
     15        (TestWebKitAPI::OverflowCrashLogger::reset):
     16        (TestWebKitAPI::OverflowCrashLogger::hasOverflowed):
     17        (TestWebKitAPI::OverflowCrashLogger::overflowCount):
     18        (TestWebKitAPI::OverflowCrashLogger::didCrash):
     19        - crash logger for verifying that a crash occurs when expected.
     20
     21        (TestWebKitAPI::resetOverflow):
     22        - convenience function for resetting a test value to an initial overflowed state
     23          before a crash.  We will use this value in the overflow testing.
     24
     25        (TestWebKitAPI::CheckedArithmeticTester::run):
     26        - Added new tests for all the comparison operators.
     27
    1282015-06-19  Per Arne Vollan  <peavo@outlook.com>
    229
  • trunk/Tools/TestWebKitAPI/Tests/WTF/CheckedArithmeticOperations.cpp

    r185711 r185755  
    2626#include "config.h"
    2727#include <wtf/CheckedArithmetic.h>
     28#include <wtf/DataLog.h> // mlam
    2829
    2930namespace TestWebKitAPI {
     31
     32class OverflowCrashLogger {
     33protected:
     34    void overflowed()
     35    {
     36        m_overflowCount++;
     37    }
     38   
     39    void clearOverflow()
     40    {
     41        m_overflowCount = 0;
     42    }
     43   
     44    static void crash()
     45    {
     46        s_didCrash = true;
     47    }
     48   
     49public:
     50    void reset()
     51    {
     52        m_overflowCount = 0;
     53        s_didCrash = false;
     54    }
     55   
     56    bool hasOverflowed() const { return m_overflowCount > 0; }
     57    int overflowCount() const { return m_overflowCount; }
     58
     59    bool didCrash() const { return s_didCrash; }
     60   
     61private:
     62    int m_overflowCount { 0 };
     63    static bool s_didCrash;
     64};
     65
     66bool OverflowCrashLogger::s_didCrash = false;
     67
     68template <typename type>
     69static void resetOverflow(Checked<type, OverflowCrashLogger>& value)
     70{
     71    value.reset();
     72    value = 100;
     73    value *= std::numeric_limits<type>::max();
     74}
    3075
    3176#define CheckedArithmeticTest(type, Coercer, MixedSignednessTester) \
     
    122167        EXPECT_EQ(true, (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).hasOverflowed());
    123168
     169
     170        Checked<type, OverflowCrashLogger> nvalue; // to hold a not overflowed value.
     171        Checked<type, OverflowCrashLogger> ovalue; // to hold an overflowed value.
     172        bool unused;
     173
     174        _value = 75;
     175        type _largeValue = 100;
     176        type _smallValue = 50;
     177
     178        value = _smallValue;
     179        nvalue = _value;
     180        ovalue = _value;
     181
     182        // Make sure the OverflowCrashLogger is working as expected.
     183        EXPECT_EQ(false, (ovalue.hasOverflowed()));
     184        EXPECT_EQ(true, (resetOverflow(ovalue), ovalue.hasOverflowed()));
     185        EXPECT_EQ(false, (resetOverflow(ovalue), ovalue.didCrash()));
     186        EXPECT_EQ(true, (unused = (ovalue == ovalue), ovalue.didCrash()));
     187        EXPECT_EQ(false, (resetOverflow(ovalue), ovalue.didCrash()));
     188
     189        EXPECT_EQ(false, nvalue.hasOverflowed());
     190        EXPECT_EQ(false, nvalue.didCrash());
     191
     192        // Test operator== that should not overflow nor crash.
     193        EXPECT_EQ(true, (nvalue == nvalue));
     194        EXPECT_EQ(true, (nvalue == Checked<type, OverflowCrashLogger>(_value)));
     195        EXPECT_EQ(false, (nvalue == value));
     196        EXPECT_EQ(true, (nvalue == _value));
     197        EXPECT_EQ(false, (nvalue == Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())));
     198        EXPECT_EQ(false, (nvalue == std::numeric_limits<type>::max()));
     199
     200        EXPECT_EQ(false, nvalue.hasOverflowed());
     201        EXPECT_EQ(false, nvalue.didCrash());
     202
     203        // Test operator!= that should not overflow nor crash.
     204        EXPECT_EQ(false, (nvalue != nvalue));
     205        EXPECT_EQ(false, (nvalue != Checked<type, OverflowCrashLogger>(_value)));
     206        EXPECT_EQ(true, (nvalue != value));
     207        EXPECT_EQ(false, (nvalue != _value));
     208        EXPECT_EQ(true, (nvalue != Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())));
     209        EXPECT_EQ(true, (nvalue != std::numeric_limits<type>::max()));
     210
     211        EXPECT_EQ(false, nvalue.hasOverflowed());
     212        EXPECT_EQ(false, nvalue.didCrash());
     213
     214        // Test operator< that should not overflow nor crash.
     215        EXPECT_EQ(false, (nvalue < nvalue));
     216        EXPECT_EQ(false, (nvalue < value));
     217        EXPECT_EQ(true, (nvalue < Checked<type, OverflowCrashLogger>(_largeValue)));
     218        EXPECT_EQ(false, (nvalue < Checked<type, OverflowCrashLogger>(_value)));
     219        EXPECT_EQ(false, (nvalue < Checked<type, OverflowCrashLogger>(_smallValue)));
     220        EXPECT_EQ(true, (nvalue < _largeValue));
     221        EXPECT_EQ(false, (nvalue < _value));
     222        EXPECT_EQ(false, (nvalue < _smallValue));
     223        EXPECT_EQ(true, (nvalue < Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())));
     224        EXPECT_EQ(true, (nvalue < std::numeric_limits<type>::max()));
     225
     226        EXPECT_EQ(false, nvalue.hasOverflowed());
     227        EXPECT_EQ(false, nvalue.didCrash());
     228
     229        // Test operator<= that should not overflow nor crash.
     230        EXPECT_EQ(true, (nvalue <= nvalue));
     231        EXPECT_EQ(false, (nvalue <= value));
     232        EXPECT_EQ(true, (nvalue <= Checked<type, OverflowCrashLogger>(_largeValue)));
     233        EXPECT_EQ(true, (nvalue <= Checked<type, OverflowCrashLogger>(_value)));
     234        EXPECT_EQ(false, (nvalue <= Checked<type, OverflowCrashLogger>(_smallValue)));
     235        EXPECT_EQ(true, (nvalue <= _largeValue));
     236        EXPECT_EQ(true, (nvalue <= _value));
     237        EXPECT_EQ(false, (nvalue <= _smallValue));
     238        EXPECT_EQ(true, (nvalue <= Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())));
     239        EXPECT_EQ(true, (nvalue <= std::numeric_limits<type>::max()));
     240
     241        EXPECT_EQ(false, nvalue.hasOverflowed());
     242        EXPECT_EQ(false, nvalue.didCrash());
     243
     244        // Test operator> that should not overflow nor crash.
     245        EXPECT_EQ(false, (nvalue > nvalue));
     246        EXPECT_EQ(true, (nvalue > value));
     247        EXPECT_EQ(false, (nvalue > Checked<type, OverflowCrashLogger>(_largeValue)));
     248        EXPECT_EQ(false, (nvalue > Checked<type, OverflowCrashLogger>(_value)));
     249        EXPECT_EQ(true, (nvalue > Checked<type, OverflowCrashLogger>(_smallValue)));
     250        EXPECT_EQ(false, (nvalue > _largeValue));
     251        EXPECT_EQ(false, (nvalue > _value));
     252        EXPECT_EQ(true, (nvalue > _smallValue));
     253        EXPECT_EQ(false, (nvalue > Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())));
     254        EXPECT_EQ(false, (nvalue > std::numeric_limits<type>::max()));
     255
     256        EXPECT_EQ(false, nvalue.hasOverflowed());
     257        EXPECT_EQ(false, nvalue.didCrash());
     258
     259        // Test operator>= that should not overflow nor crash.
     260        EXPECT_EQ(true, (nvalue >= nvalue));
     261        EXPECT_EQ(true, (nvalue >= value));
     262        EXPECT_EQ(false, (nvalue >= Checked<type, OverflowCrashLogger>(_largeValue)));
     263        EXPECT_EQ(true, (nvalue >= Checked<type, OverflowCrashLogger>(_value)));
     264        EXPECT_EQ(true, (nvalue >= Checked<type, OverflowCrashLogger>(_smallValue)));
     265        EXPECT_EQ(false, (nvalue >= _largeValue));
     266        EXPECT_EQ(true, (nvalue >= _value));
     267        EXPECT_EQ(true, (nvalue >= _smallValue));
     268        EXPECT_EQ(false, (nvalue >= Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())));
     269        EXPECT_EQ(false, (nvalue >= std::numeric_limits<type>::max()));
     270
     271        EXPECT_EQ(false, nvalue.hasOverflowed());
     272        EXPECT_EQ(false, nvalue.didCrash());
     273
     274        // Test operator== with an overflowed value.
     275        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == ovalue), ovalue.didCrash()));
     276        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == Checked<type, OverflowCrashLogger>(_value)), ovalue.didCrash()));
     277        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == value), ovalue.didCrash()));
     278        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == _value), ovalue.didCrash()));
     279        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == _value * std::numeric_limits<type>::max()), ovalue.didCrash()));
     280        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())), ovalue.didCrash()));
     281        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == std::numeric_limits<type>::max()), ovalue.didCrash()));
     282        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == nvalue), ovalue.didCrash()));
     283        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (nvalue == ovalue), ovalue.didCrash()));
     284
     285        EXPECT_EQ(false, nvalue.hasOverflowed());
     286
     287        // Test operator!= with an overflowed value.
     288        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != ovalue), ovalue.didCrash()));
     289        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != Checked<type, OverflowCrashLogger>(_value)), ovalue.didCrash()));
     290        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != value), ovalue.didCrash()));
     291        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != _value), ovalue.didCrash()));
     292        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != _value * std::numeric_limits<type>::max()), ovalue.didCrash()));
     293        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())), ovalue.didCrash()));
     294        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != std::numeric_limits<type>::max()), ovalue.didCrash()));
     295        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != nvalue), ovalue.didCrash()));
     296        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (nvalue != ovalue), ovalue.didCrash()));
     297
     298        EXPECT_EQ(false, nvalue.hasOverflowed());
     299
     300        // Test operator< with an overflowed value.
     301        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < ovalue), ovalue.didCrash()));
     302        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < value), ovalue.didCrash()));
     303        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < Checked<type, OverflowCrashLogger>(_largeValue)), ovalue.didCrash()));
     304        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < Checked<type, OverflowCrashLogger>(_value)), ovalue.didCrash()));
     305        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < Checked<type, OverflowCrashLogger>(_smallValue)), ovalue.didCrash()));
     306        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < _largeValue), ovalue.didCrash()));
     307        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < _value), ovalue.didCrash()));
     308        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < _smallValue), ovalue.didCrash()));
     309        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())), ovalue.didCrash()));
     310        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < std::numeric_limits<type>::max()), ovalue.didCrash()));
     311        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < nvalue), ovalue.didCrash()));
     312        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (nvalue < ovalue), ovalue.didCrash()));
     313
     314        EXPECT_EQ(false, nvalue.hasOverflowed());
     315
     316        // Test operator<= with an overflowed value.
     317        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= ovalue), ovalue.didCrash()));
     318        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= value), ovalue.didCrash()));
     319        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= Checked<type, OverflowCrashLogger>(_largeValue)), ovalue.didCrash()));
     320        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= Checked<type, OverflowCrashLogger>(_value)), ovalue.didCrash()));
     321        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= Checked<type, OverflowCrashLogger>(_smallValue)), ovalue.didCrash()));
     322        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= _largeValue), ovalue.didCrash()));
     323        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= _value), ovalue.didCrash()));
     324        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= _smallValue), ovalue.didCrash()));
     325        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())), ovalue.didCrash()));
     326        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= std::numeric_limits<type>::max()), ovalue.didCrash()));
     327        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= nvalue), ovalue.didCrash()));
     328        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (nvalue <= ovalue), ovalue.didCrash()));
     329
     330        EXPECT_EQ(false, nvalue.hasOverflowed());
     331
     332        // Test operator> with an overflowed value.
     333        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > ovalue), ovalue.didCrash()));
     334        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > value), ovalue.didCrash()));
     335        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > Checked<type, OverflowCrashLogger>(_largeValue)), ovalue.didCrash()));
     336        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > Checked<type, OverflowCrashLogger>(_value)), ovalue.didCrash()));
     337        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > Checked<type, OverflowCrashLogger>(_smallValue)), ovalue.didCrash()));
     338        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > _largeValue), ovalue.didCrash()));
     339        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > _value), ovalue.didCrash()));
     340        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > _smallValue), ovalue.didCrash()));
     341        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())), ovalue.didCrash()));
     342        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > std::numeric_limits<type>::max()), ovalue.didCrash()));
     343        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > nvalue), ovalue.didCrash()));
     344        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (nvalue > ovalue), ovalue.didCrash()));
     345
     346        EXPECT_EQ(false, nvalue.hasOverflowed());
     347
     348        // Test operator>= with an overflowed value.
     349        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= ovalue), ovalue.didCrash()));
     350        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= value), ovalue.didCrash()));
     351        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= Checked<type, OverflowCrashLogger>(_largeValue)), ovalue.didCrash()));
     352        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= Checked<type, OverflowCrashLogger>(_value)), ovalue.didCrash()));
     353        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= Checked<type, OverflowCrashLogger>(_smallValue)), ovalue.didCrash()));
     354        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= _largeValue), ovalue.didCrash()));
     355        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= _value), ovalue.didCrash()));
     356        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= _smallValue), ovalue.didCrash()));
     357        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())), ovalue.didCrash()));
     358        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= std::numeric_limits<type>::max()), ovalue.didCrash()));
     359        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= nvalue), ovalue.didCrash()));
     360        EXPECT_EQ(true, (resetOverflow(ovalue), unused = (nvalue >= ovalue), ovalue.didCrash()));
     361
     362        EXPECT_EQ(false, nvalue.hasOverflowed());
     363
    124364        MixedSignednessTester::run();
    125365    }
Note: See TracChangeset for help on using the changeset viewer.