diff --git a/Utilities/address_range.h b/Utilities/address_range.h index ba07651b4e..8da0279ef1 100644 --- a/Utilities/address_range.h +++ b/Utilities/address_range.h @@ -81,7 +81,8 @@ namespace utils return {}; } - return {_start, _start + (_length - 1)}; + const T _end = static_cast(_start + _length - 1); + return {_start, _end}; } static constexpr address_range start_end(T _start, T _end) diff --git a/rpcs3/CMakeLists.txt b/rpcs3/CMakeLists.txt index 727bee8cae..395ea52e87 100644 --- a/rpcs3/CMakeLists.txt +++ b/rpcs3/CMakeLists.txt @@ -200,6 +200,7 @@ if(BUILD_RPCS3_TESTS) tests/test.cpp tests/test_fmt.cpp tests/test_simple_array.cpp + tests/test_address_range.cpp ) target_link_libraries(rpcs3_test diff --git a/rpcs3/tests/test_address_range.cpp b/rpcs3/tests/test_address_range.cpp index 44ad134646..5a7e8b2faf 100644 --- a/rpcs3/tests/test_address_range.cpp +++ b/rpcs3/tests/test_address_range.cpp @@ -447,4 +447,51 @@ namespace utils EXPECT_EQ(hasher(r1), hasher(r2)); EXPECT_NE(hasher(r1), hasher(r3)); } + + // Test invalidation rules around umax + TEST(AddressRange, Invalidate32) + { + address_range32 r1 = address_range32::start_length(0x0, 0x1000); + r1.invalidate(); + + EXPECT_FALSE(r1.valid()); + EXPECT_EQ(r1.start, 0xffff'ffffu); + EXPECT_EQ(r1.end, 0u); + } + + TEST(AddressRange, Invalidate64) + { + address_range64 r1 = address_range64::start_length(0x0, 0x1000); + r1.invalidate(); + + EXPECT_FALSE(r1.valid()); + EXPECT_EQ(r1.start, 0xffff'ffff'ffff'ffffull); + EXPECT_EQ(r1.end, 0ull); + } + + TEST(AddressRange, Invalidate16) + { + const u16 start = 0x1000, length = 0x1000; + address_range16 r1 = address_range16::start_length(start, length); + r1.invalidate(); + + EXPECT_FALSE(r1.valid()); + EXPECT_EQ(r1.start, 0xffff); + EXPECT_EQ(r1.end, 0); + } + + TEST(AddressRange, InvalidConstruction) + { + address_range32 r1 = address_range32::start_length(umax, u32{umax} / 2); + EXPECT_FALSE(r1.valid()); + } + + TEST(AddressRange, LargeValues64) + { + const u32 start = umax, length = u32{umax} / 2; + address_range64 r1 = address_range64::start_length(start, length); + + EXPECT_EQ(r1.start, 0xffff'ffffull); + EXPECT_EQ(r1.end, 0x1'7fff'fffd); + } }