1
0
Fork 0
mirror of https://github.com/LadybirdBrowser/ladybird.git synced 2025-06-08 05:27:14 +09:00

AK/Checked: Dont verify overflow bit in lvalue operations

Before, adding an overflow'n `Checked<T>` to another `Checked<T>` would
cause a verification faliure when instead it should propogate m_overflow
and allow the user to handle the overflow.
This commit is contained in:
Jess 2025-02-20 03:05:16 +13:00 committed by Sam Atkins
parent e5966eed08
commit 88c4f71114
Notes: github-actions[bot] 2025-02-25 11:21:17 +00:00
2 changed files with 53 additions and 10 deletions

View file

@ -255,7 +255,7 @@ public:
constexpr Checked& operator+=(Checked const& other)
{
m_overflow |= other.m_overflow;
add(other.value());
add(other.value_unchecked());
return *this;
}
@ -268,7 +268,7 @@ public:
constexpr Checked& operator-=(Checked const& other)
{
m_overflow |= other.m_overflow;
sub(other.value());
sub(other.value_unchecked());
return *this;
}
@ -281,7 +281,7 @@ public:
constexpr Checked& operator*=(Checked const& other)
{
m_overflow |= other.m_overflow;
mul(other.value());
mul(other.value_unchecked());
return *this;
}
@ -294,7 +294,7 @@ public:
constexpr Checked& operator/=(Checked const& other)
{
m_overflow |= other.m_overflow;
div(other.value());
div(other.value_unchecked());
return *this;
}
@ -307,7 +307,7 @@ public:
constexpr Checked& operator%=(Checked const& other)
{
m_overflow |= other.m_overflow;
mod(other.value());
mod(other.value_unchecked());
return *this;
}
@ -434,7 +434,7 @@ template<typename T>
constexpr Checked<T> operator+(Checked<T> const& a, Checked<T> const& b)
{
Checked<T> c { a };
c.add(b.value());
c += b;
return c;
}
@ -442,7 +442,7 @@ template<typename T>
constexpr Checked<T> operator-(Checked<T> const& a, Checked<T> const& b)
{
Checked<T> c { a };
c.sub(b.value());
c -= b;
return c;
}
@ -450,7 +450,7 @@ template<typename T>
constexpr Checked<T> operator*(Checked<T> const& a, Checked<T> const& b)
{
Checked<T> c { a };
c.mul(b.value());
c *= b;
return c;
}
@ -458,7 +458,7 @@ template<typename T>
constexpr Checked<T> operator/(Checked<T> const& a, Checked<T> const& b)
{
Checked<T> c { a };
c.div(b.value());
c /= b;
return c;
}
@ -466,7 +466,7 @@ template<typename T>
constexpr Checked<T> operator%(Checked<T> const& a, Checked<T> const& b)
{
Checked<T> c { a };
c.mod(b.value());
c %= b;
return c;
}

View file

@ -135,6 +135,49 @@ TEST_CASE(detects_unsigned_overflow)
EXPECT((Checked<u64>(0x4000000000000000) - Checked<u64>(0x4000000000000001)).has_overflow());
}
TEST_CASE(operations_with_overflowed)
{
{
Checked<u32> overflowed(0x100000000);
EXPECT((Checked<u32>(0x100000000) + Checked<u32>(0xff)).has_overflow());
EXPECT((Checked<u32>(0xff) + Checked<u32>(0x100000000)).has_overflow());
EXPECT((overflowed += Checked<u32>(0xff)).has_overflow());
EXPECT((overflowed += Checked<u32>(0x100000000)).has_overflow());
}
{
Checked<u32> overflowed(0x100000000);
EXPECT((Checked<u32>(0x100000000) - Checked<u32>(0xff)).has_overflow());
EXPECT((Checked<u32>(0xff) - Checked<u32>(0x100000000)).has_overflow());
EXPECT((overflowed -= Checked<u32>(0xff)).has_overflow());
EXPECT((overflowed -= Checked<u32>(0x100000000)).has_overflow());
}
{
Checked<u32> overflowed(0x100000000);
EXPECT((Checked<u32>(0x100000000) * Checked<u32>(0xff)).has_overflow());
EXPECT((Checked<u32>(0xff) * Checked<u32>(0x100000000)).has_overflow());
EXPECT((overflowed *= Checked<u32>(0xff)).has_overflow());
EXPECT((overflowed *= Checked<u32>(0x100000000)).has_overflow());
}
{
Checked<u32> overflowed(0x100000000);
EXPECT((Checked<u32>(0x100000000) / Checked<u32>(0xff)).has_overflow());
EXPECT((Checked<u32>(0xff) / Checked<u32>(0x100000000)).has_overflow());
EXPECT((overflowed /= Checked<u32>(0xff)).has_overflow());
EXPECT((overflowed /= Checked<u32>(0x100000000)).has_overflow());
}
{
Checked<u32> overflowed(0x100000000);
EXPECT((Checked<u32>(0x100000000) % Checked<u32>(0xff)).has_overflow());
EXPECT((Checked<u32>(0xff) % Checked<u32>(0x100000000)).has_overflow());
EXPECT((overflowed %= Checked<u32>(0xff)).has_overflow());
EXPECT((overflowed %= Checked<u32>(0x100000000)).has_overflow());
}
}
TEST_CASE(should_constexpr_default_construct)
{
constexpr Checked<int> checked_value {};