Changeset 185708 in webkit
- Timestamp:
- Jun 18, 2015, 10:58:22 AM (10 years ago)
- Location:
- trunk/Tools
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Tools/ChangeLog
r185701 r185708 1 2015-06-18 Mark Lam <mark.lam@apple.com> 2 3 Refactor CheckedArithmeticOperations.cpp to use templates instead of macros. 4 https://bugs.webkit.org/show_bug.cgi?id=146103 5 6 Reviewed by Anders Carlsson. 7 8 Presently, the tests in CheckedArithmeticOperations.cpp are all implemented as 9 part of a large macro. This makes them harder to: 10 11 1. write: no editor help with indentations, have to add trailing '\'s, 12 inconvenient to add line breaks and comments. 13 14 2. read: no chroma coding / syntax highlighting. 15 16 3. debug: compile time errors are reported as being on the single line where 17 the macro is used. 18 19 Refactoring the tests to use C++ templates solves all these issues. 20 21 * TestWebKitAPI/Tests/WTF/CheckedArithmeticOperations.cpp: 22 (TestWebKitAPI::CheckedArithmeticTester::run): 23 (TestWebKitAPI::AllowMixedSignednessTest::run): 24 (TestWebKitAPI::IgnoreMixedSignednessTest::run): 25 (TestWebKitAPI::CoerceLiteralToUnsigned::coerce): 26 (TestWebKitAPI::CoerceLiteralNop::coerce): 27 1 28 2015-06-18 Christophe Dumez <ch.dumez@sisa.samsung.com> 2 29 -
trunk/Tools/TestWebKitAPI/Tests/WTF/CheckedArithmeticOperations.cpp
r145759 r185708 1 1 /* 2 * Copyright (C) 2011 Apple Inc. All rights reserved.2 * Copyright (C) 2011, 2015 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 29 29 namespace TestWebKitAPI { 30 30 31 #define CheckedArithmeticTest(type, coerceLiteral, MixedSignednessTest) \31 #define CheckedArithmeticTest(type, Coercer, MixedSignednessTester) \ 32 32 TEST(WTF, Checked_##type) \ 33 33 { \ 34 Checked<type, RecordOverflow> value; \ 35 EXPECT_EQ(coerceLiteral(0), value.unsafeGet()); \ 36 EXPECT_EQ(std::numeric_limits<type>::max(), (value + std::numeric_limits<type>::max()).unsafeGet()); \ 37 EXPECT_EQ(std::numeric_limits<type>::max(), (std::numeric_limits<type>::max() + value).unsafeGet()); \ 38 EXPECT_EQ(std::numeric_limits<type>::min(), (value + std::numeric_limits<type>::min()).unsafeGet()); \ 39 EXPECT_EQ(std::numeric_limits<type>::min(), (std::numeric_limits<type>::min() + value).unsafeGet()); \ 40 EXPECT_EQ(coerceLiteral(0), (value * coerceLiteral(0)).unsafeGet()); \ 41 EXPECT_EQ(coerceLiteral(0), (coerceLiteral(0) * value).unsafeGet()); \ 42 EXPECT_EQ(coerceLiteral(0), (value * value).unsafeGet()); \ 43 EXPECT_EQ(coerceLiteral(0), (value - coerceLiteral(0)).unsafeGet()); \ 44 EXPECT_EQ(coerceLiteral(0), (coerceLiteral(0) - value).unsafeGet()); \ 45 EXPECT_EQ(coerceLiteral(0), (value - value).unsafeGet()); \ 46 EXPECT_EQ(coerceLiteral(0), (value++).unsafeGet()); \ 47 EXPECT_EQ(coerceLiteral(1), (value--).unsafeGet()); \ 48 EXPECT_EQ(coerceLiteral(1), (++value).unsafeGet()); \ 49 EXPECT_EQ(coerceLiteral(0), (--value).unsafeGet()); \ 50 EXPECT_EQ(coerceLiteral(10), (value += coerceLiteral(10)).unsafeGet()); \ 51 EXPECT_EQ(coerceLiteral(10), value.unsafeGet()); \ 52 EXPECT_EQ(coerceLiteral(100), (value *= coerceLiteral(10)).unsafeGet()); \ 53 EXPECT_EQ(coerceLiteral(100), value.unsafeGet()); \ 54 EXPECT_EQ(coerceLiteral(0), (value -= coerceLiteral(100)).unsafeGet()); \ 55 EXPECT_EQ(coerceLiteral(0), value.unsafeGet()); \ 56 value = 10; \ 57 EXPECT_EQ(coerceLiteral(10), value.unsafeGet()); \ 58 EXPECT_EQ(coerceLiteral(0), (value - coerceLiteral(10)).unsafeGet()); \ 59 EXPECT_EQ(coerceLiteral(10), value.unsafeGet()); \ 60 value = std::numeric_limits<type>::min(); \ 61 EXPECT_EQ(true, (Checked<type, RecordOverflow>(value - coerceLiteral(1))).hasOverflowed()); \ 62 EXPECT_EQ(true, !((value--).hasOverflowed())); \ 63 EXPECT_EQ(true, value.hasOverflowed()); \ 64 value = std::numeric_limits<type>::max(); \ 65 EXPECT_EQ(true, !value.hasOverflowed()); \ 66 EXPECT_EQ(true, (Checked<type, RecordOverflow>(value + coerceLiteral(1))).hasOverflowed()); \ 67 EXPECT_EQ(true, !(value++).hasOverflowed()); \ 68 EXPECT_EQ(true, value.hasOverflowed()); \ 69 value = std::numeric_limits<type>::max(); \ 70 EXPECT_EQ(true, (value += coerceLiteral(1)).hasOverflowed()); \ 71 EXPECT_EQ(true, value.hasOverflowed()); \ 72 value = 10; \ 73 type _value = 0; \ 74 EXPECT_EQ(true, CheckedState::DidNotOverflow == (value * Checked<type, RecordOverflow>(0)).safeGet(_value)); \ 75 _value = 0; \ 76 EXPECT_EQ(true, CheckedState::DidNotOverflow == (Checked<type, RecordOverflow>(0) * value).safeGet(_value)); \ 77 _value = 0; \ 78 EXPECT_EQ(true, CheckedState::DidOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value)); \ 79 _value = 0; \ 80 EXPECT_EQ(true, CheckedState::DidOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * value).safeGet(_value)); \ 81 value = 0; \ 82 _value = 0; \ 83 EXPECT_EQ(true, CheckedState::DidNotOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value)); \ 84 _value = 0; \ 85 EXPECT_EQ(true, CheckedState::DidNotOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * value).safeGet(_value)); \ 86 value = 1; \ 87 _value = 0; \ 88 EXPECT_EQ(true, CheckedState::DidNotOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value)); \ 89 _value = 0; \ 90 EXPECT_EQ(true, CheckedState::DidNotOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * value).safeGet(_value)); \ 91 _value = 0; \ 92 value = 0; \ 93 EXPECT_EQ(true, CheckedState::DidNotOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value)); \ 94 _value = 0; \ 95 EXPECT_EQ(true, CheckedState::DidNotOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * (type)0).safeGet(_value)); \ 96 _value = 0; \ 97 value = 1; \ 98 EXPECT_EQ(true, CheckedState::DidNotOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value)); \ 99 _value = 0; \ 100 EXPECT_EQ(true, CheckedState::DidNotOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * (type)1).safeGet(_value)); \ 101 _value = 0; \ 102 value = 2; \ 103 EXPECT_EQ(true, CheckedState::DidOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value)); \ 104 _value = 0; \ 105 EXPECT_EQ(true, CheckedState::DidOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * (type)2).safeGet(_value)); \ 106 value = 10; \ 107 EXPECT_EQ(true, (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).hasOverflowed()); \ 108 MixedSignednessTest(EXPECT_EQ(coerceLiteral(0), (value + -10).unsafeGet())); \ 109 MixedSignednessTest(EXPECT_EQ(0U, (value - 10U).unsafeGet())); \ 110 MixedSignednessTest(EXPECT_EQ(coerceLiteral(0), (-10 + value).unsafeGet())); \ 111 MixedSignednessTest(EXPECT_EQ(0U, (10U - value).unsafeGet())); \ 112 value = std::numeric_limits<type>::min(); \ 113 MixedSignednessTest(EXPECT_EQ(true, (Checked<type, RecordOverflow>(value - 1)).hasOverflowed())); \ 114 MixedSignednessTest(EXPECT_EQ(true, !(value--).hasOverflowed())); \ 115 MixedSignednessTest(EXPECT_EQ(true, value.hasOverflowed())); \ 116 value = std::numeric_limits<type>::max(); \ 117 MixedSignednessTest(EXPECT_EQ(true, !value.hasOverflowed())); \ 118 MixedSignednessTest(EXPECT_EQ(true, (Checked<type, RecordOverflow>(value + 1)).hasOverflowed())); \ 119 MixedSignednessTest(EXPECT_EQ(true, !(value++).hasOverflowed())); \ 120 MixedSignednessTest(EXPECT_EQ(true, value.hasOverflowed())); \ 121 value = std::numeric_limits<type>::max(); \ 122 MixedSignednessTest(EXPECT_EQ(true, (value += 1).hasOverflowed())); \ 123 MixedSignednessTest(EXPECT_EQ(true, value.hasOverflowed())); \ 124 value = std::numeric_limits<type>::min(); \ 125 MixedSignednessTest(EXPECT_EQ(true, (value - 1U).hasOverflowed())); \ 126 MixedSignednessTest(EXPECT_EQ(true, !(value--).hasOverflowed())); \ 127 MixedSignednessTest(EXPECT_EQ(true, value.hasOverflowed())); \ 128 value = std::numeric_limits<type>::max(); \ 129 MixedSignednessTest(EXPECT_EQ(true, !value.hasOverflowed())); \ 130 MixedSignednessTest(EXPECT_EQ(true, (Checked<type, RecordOverflow>(value + 1U)).hasOverflowed())); \ 131 MixedSignednessTest(EXPECT_EQ(true, !(value++).hasOverflowed())); \ 132 MixedSignednessTest(EXPECT_EQ(true, value.hasOverflowed())); \ 133 value = std::numeric_limits<type>::max(); \ 134 MixedSignednessTest(EXPECT_EQ(true, (value += 1U).hasOverflowed())); \ 135 MixedSignednessTest(EXPECT_EQ(true, value.hasOverflowed())); \ 34 typedef Coercer<type> CoercerType; \ 35 typedef MixedSignednessTester<type, CoercerType> MixedSignednessTesterType; \ 36 CheckedArithmeticTester<type, CoercerType, MixedSignednessTesterType>(); \ 136 37 } 38 39 #define coerceLiteral(x) Coerser::coerce(x) 40 41 template <typename type, typename Coerser, typename MixedSignednessTester> 42 class CheckedArithmeticTester { 43 public: 44 static void run() 45 { 46 Checked<type, RecordOverflow> value; 47 EXPECT_EQ(coerceLiteral(0), value.unsafeGet()); 48 EXPECT_EQ(std::numeric_limits<type>::max(), (value + std::numeric_limits<type>::max()).unsafeGet()); 49 EXPECT_EQ(std::numeric_limits<type>::max(), (std::numeric_limits<type>::max() + value).unsafeGet()); 50 EXPECT_EQ(std::numeric_limits<type>::min(), (value + std::numeric_limits<type>::min()).unsafeGet()); 51 EXPECT_EQ(std::numeric_limits<type>::min(), (std::numeric_limits<type>::min() + value).unsafeGet()); 137 52 138 #define CoerceLiteralToUnsigned(x) x##U 139 #define CoerceLiteralNop(x) x 140 #define AllowMixedSignednessTest(x) x 141 #define IgnoreMixedSignednessTest(x) 53 EXPECT_EQ(coerceLiteral(0), (value * coerceLiteral(0)).unsafeGet()); 54 EXPECT_EQ(coerceLiteral(0), (coerceLiteral(0) * value).unsafeGet()); 55 EXPECT_EQ(coerceLiteral(0), (value * value).unsafeGet()); 56 EXPECT_EQ(coerceLiteral(0), (value - coerceLiteral(0)).unsafeGet()); 57 EXPECT_EQ(coerceLiteral(0), (coerceLiteral(0) - value).unsafeGet()); 58 EXPECT_EQ(coerceLiteral(0), (value - value).unsafeGet()); 59 EXPECT_EQ(coerceLiteral(0), (value++).unsafeGet()); 60 EXPECT_EQ(coerceLiteral(1), (value--).unsafeGet()); 61 EXPECT_EQ(coerceLiteral(1), (++value).unsafeGet()); 62 EXPECT_EQ(coerceLiteral(0), (--value).unsafeGet()); 63 EXPECT_EQ(coerceLiteral(10), (value += coerceLiteral(10)).unsafeGet()); 64 EXPECT_EQ(coerceLiteral(10), value.unsafeGet()); 65 EXPECT_EQ(coerceLiteral(100), (value *= coerceLiteral(10)).unsafeGet()); 66 EXPECT_EQ(coerceLiteral(100), value.unsafeGet()); 67 EXPECT_EQ(coerceLiteral(0), (value -= coerceLiteral(100)).unsafeGet()); 68 EXPECT_EQ(coerceLiteral(0), value.unsafeGet()); 69 value = 10; 70 EXPECT_EQ(coerceLiteral(10), value.unsafeGet()); 71 EXPECT_EQ(coerceLiteral(0), (value - coerceLiteral(10)).unsafeGet()); 72 EXPECT_EQ(coerceLiteral(10), value.unsafeGet()); 73 74 value = std::numeric_limits<type>::min(); 75 EXPECT_EQ(true, (Checked<type, RecordOverflow>(value - coerceLiteral(1))).hasOverflowed()); 76 EXPECT_EQ(true, !((value--).hasOverflowed())); 77 EXPECT_EQ(true, value.hasOverflowed()); 78 value = std::numeric_limits<type>::max(); 79 EXPECT_EQ(true, !value.hasOverflowed()); 80 EXPECT_EQ(true, (Checked<type, RecordOverflow>(value + coerceLiteral(1))).hasOverflowed()); 81 EXPECT_EQ(true, !(value++).hasOverflowed()); 82 EXPECT_EQ(true, value.hasOverflowed()); 83 value = std::numeric_limits<type>::max(); 84 EXPECT_EQ(true, (value += coerceLiteral(1)).hasOverflowed()); 85 EXPECT_EQ(true, value.hasOverflowed()); 86 87 value = 10; 88 type _value = 0; 89 EXPECT_EQ(true, CheckedState::DidNotOverflow == (value * Checked<type, RecordOverflow>(0)).safeGet(_value)); 90 _value = 0; 91 EXPECT_EQ(true, CheckedState::DidNotOverflow == (Checked<type, RecordOverflow>(0) * value).safeGet(_value)); 92 _value = 0; 93 EXPECT_EQ(true, CheckedState::DidOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value)); 94 _value = 0; 95 EXPECT_EQ(true, CheckedState::DidOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * value).safeGet(_value)); 96 value = 0; 97 _value = 0; 98 EXPECT_EQ(true, CheckedState::DidNotOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value)); 99 _value = 0; 100 EXPECT_EQ(true, CheckedState::DidNotOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * value).safeGet(_value)); 101 value = 1; 102 _value = 0; 103 EXPECT_EQ(true, CheckedState::DidNotOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value)); 104 _value = 0; 105 EXPECT_EQ(true, CheckedState::DidNotOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * value).safeGet(_value)); 106 _value = 0; 107 value = 0; 108 EXPECT_EQ(true, CheckedState::DidNotOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value)); 109 _value = 0; 110 EXPECT_EQ(true, CheckedState::DidNotOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * (type)0).safeGet(_value)); 111 _value = 0; 112 value = 1; 113 EXPECT_EQ(true, CheckedState::DidNotOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value)); 114 _value = 0; 115 EXPECT_EQ(true, CheckedState::DidNotOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * (type)1).safeGet(_value)); 116 _value = 0; 117 value = 2; 118 EXPECT_EQ(true, CheckedState::DidOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value)); 119 _value = 0; 120 EXPECT_EQ(true, CheckedState::DidOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * (type)2).safeGet(_value)); 121 value = 10; 122 EXPECT_EQ(true, (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).hasOverflowed()); 123 124 MixedSignednessTester::run(); 125 } 126 }; 127 128 template <typename type, typename Coerser> 129 class AllowMixedSignednessTest { 130 public: 131 static void run() 132 { 133 Checked<type, RecordOverflow> value; 134 value = 10; 135 136 EXPECT_EQ(coerceLiteral(0), (value + -10).unsafeGet()); 137 EXPECT_EQ(0U, (value - 10U).unsafeGet()); 138 EXPECT_EQ(coerceLiteral(0), (-10 + value).unsafeGet()); 139 EXPECT_EQ(0U, (10U - value).unsafeGet()); 140 value = std::numeric_limits<type>::min(); 141 EXPECT_EQ(true, (Checked<type, RecordOverflow>(value - 1)).hasOverflowed()); 142 EXPECT_EQ(true, !(value--).hasOverflowed()); 143 EXPECT_EQ(true, value.hasOverflowed()); 144 value = std::numeric_limits<type>::max(); 145 EXPECT_EQ(true, !value.hasOverflowed()); 146 EXPECT_EQ(true, (Checked<type, RecordOverflow>(value + 1)).hasOverflowed()); 147 EXPECT_EQ(true, !(value++).hasOverflowed()); 148 EXPECT_EQ(true, value.hasOverflowed()); 149 value = std::numeric_limits<type>::max(); 150 EXPECT_EQ(true, (value += 1).hasOverflowed()); 151 EXPECT_EQ(true, value.hasOverflowed()); 152 value = std::numeric_limits<type>::min(); 153 EXPECT_EQ(true, (value - 1U).hasOverflowed()); 154 EXPECT_EQ(true, !(value--).hasOverflowed()); 155 EXPECT_EQ(true, value.hasOverflowed()); 156 value = std::numeric_limits<type>::max(); 157 EXPECT_EQ(true, !value.hasOverflowed()); 158 EXPECT_EQ(true, (Checked<type, RecordOverflow>(value + 1U)).hasOverflowed()); 159 EXPECT_EQ(true, !(value++).hasOverflowed()); 160 EXPECT_EQ(true, value.hasOverflowed()); 161 value = std::numeric_limits<type>::max(); 162 EXPECT_EQ(true, (value += 1U).hasOverflowed()); 163 EXPECT_EQ(true, value.hasOverflowed()); 164 } 165 }; 166 167 template <typename type, typename Coerser> 168 class IgnoreMixedSignednessTest { 169 public: 170 static void run() { } 171 }; 172 173 template <typename type> class CoerceLiteralToUnsigned { 174 public: 175 static unsigned coerce(type x) { return static_cast<unsigned>(x); } 176 }; 177 178 template <typename type> class CoerceLiteralNop { 179 public: 180 static type coerce(type x) { return x; } 181 }; 182 142 183 CheckedArithmeticTest(int8_t, CoerceLiteralNop, IgnoreMixedSignednessTest) 143 184 CheckedArithmeticTest(int16_t, CoerceLiteralNop, IgnoreMixedSignednessTest)
Note:
See TracChangeset
for help on using the changeset viewer.