From 58c5ae3de92015f8b4c3ae4b63e23b8669798edc Mon Sep 17 00:00:00 2001 From: Dentomologist Date: Sun, 31 Dec 2023 02:02:22 -0800 Subject: [PATCH 1/2] UnitTests: Refactor BitSetTest Group numbers and their bitcounts together in pairs, which allows for range-based loop iteration. --- Source/UnitTests/Common/BitSetTest.cpp | 37 +++++++++++++++++--------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/Source/UnitTests/Common/BitSetTest.cpp b/Source/UnitTests/Common/BitSetTest.cpp index 21c211516c..6ec2b74bdb 100644 --- a/Source/UnitTests/Common/BitSetTest.cpp +++ b/Source/UnitTests/Common/BitSetTest.cpp @@ -1,6 +1,9 @@ // Copyright 2014 Dolphin Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include +#include + #include #include "Common/BitSet.h" @@ -29,23 +32,31 @@ TEST(BitSet, BitGetSet) TEST(BitSet, Count) { - u32 random_numbers[] = {0x2cb0b5f3, 0x81ab32a6, 0xd9030dc5, 0x325ffe26, 0xb2fcaee3, - 0x4ccf188a, 0xf8be36dc, 0xb2fcecd5, 0xb750c2e5, 0x31d19074, - 0xf267644a, 0xac00a719, 0x6d45f19b, 0xf7e91c5b, 0xf687e694, - 0x9057c24e, 0x5eb65c39, 0x85d3038b, 0x101f4e66, 0xc202d136}; - u32 counts[] = {17, 14, 14, 19, 20, 14, 20, 20, 16, 13, 16, 12, 18, 20, 18, 14, 18, 14, 14, 12}; - for (size_t i = 0; i < 20; i++) + constexpr std::array, 20> random_32bit_number_bitcount_pairs = { + {{0x2cb0b5f3, 17}, {0x81ab32a6, 14}, {0xd9030dc5, 14}, {0x325ffe26, 19}, {0xb2fcaee3, 20}, + {0x4ccf188a, 14}, {0xf8be36dc, 20}, {0xb2fcecd5, 20}, {0xb750c2e5, 16}, {0x31d19074, 13}, + {0xf267644a, 16}, {0xac00a719, 12}, {0x6d45f19b, 18}, {0xf7e91c5b, 20}, {0xf687e694, 18}, + {0x9057c24e, 14}, {0x5eb65c39, 18}, {0x85d3038b, 14}, {0x101f4e66, 14}, {0xc202d136, 12}}}; + for (const auto& [number, bitcount] : random_32bit_number_bitcount_pairs) { - EXPECT_EQ(counts[i], BitSet32(random_numbers[i]).Count()); + const auto bitset = BitSet32(number); + EXPECT_EQ(bitset.Count(), bitcount); } - u64 random_numbers_64[] = {0xf86cd6f6ef09d7d4ULL, 0x6f2d8533255ead3cULL, 0x9da7941e0e52b345ULL, - 0x06e4189be67d2b17ULL, 0x3eb0681f65cb6d25ULL, 0xccab8a7c74a51203ULL, - 0x09d470516694c64bULL, 0x38cd077e075c778fULL, 0xd69ebfa6355ebfdeULL}; - u32 counts_64[] = {39, 34, 31, 32, 33, 29, 27, 35, 43}; - for (size_t i = 0; i < 9; i++) + constexpr std::array, 9> random_64bit_number_bitcount_pairs = { + {{0xf86cd6f6ef09d7d4ULL, 39}, + {0x6f2d8533255ead3cULL, 34}, + {0x9da7941e0e52b345ULL, 31}, + {0x06e4189be67d2b17ULL, 32}, + {0x3eb0681f65cb6d25ULL, 33}, + {0xccab8a7c74a51203ULL, 29}, + {0x09d470516694c64bULL, 27}, + {0x38cd077e075c778fULL, 35}, + {0xd69ebfa6355ebfdeULL, 43}}}; + for (const auto& [number, bitcount] : random_64bit_number_bitcount_pairs) { - EXPECT_EQ(counts_64[i], BitSet64(random_numbers_64[i]).Count()); + const auto bitset = BitSet64(number); + EXPECT_EQ(bitset.Count(), bitcount); } } From 7dbf463ddf4a89ec7158c955b421adb77670d37e Mon Sep 17 00:00:00 2001 From: Dentomologist Date: Sun, 31 Dec 2023 11:57:16 -0800 Subject: [PATCH 2/2] BitSet64: Fix iterator incrementation Use 1 of the same type as the stored value when shifting left. This prevents undefined behavior caused by shifting an int more than 31 bits. Previously iterator incrementation could either hang or prematurely report it had reached the end of the bitset. --- Source/Core/Common/BitSet.h | 2 +- Source/UnitTests/Common/BitSetTest.cpp | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Source/Core/Common/BitSet.h b/Source/Core/Common/BitSet.h index 5d2c88294d..f14ebea9e2 100644 --- a/Source/Core/Common/BitSet.h +++ b/Source/Core/Common/BitSet.h @@ -73,7 +73,7 @@ public: else { int bit = std::countr_zero(m_val); - m_val &= ~(1 << bit); + m_val &= ~(IntTy{1} << bit); m_bit = bit; } return *this; diff --git a/Source/UnitTests/Common/BitSetTest.cpp b/Source/UnitTests/Common/BitSetTest.cpp index 6ec2b74bdb..397f9fecbe 100644 --- a/Source/UnitTests/Common/BitSetTest.cpp +++ b/Source/UnitTests/Common/BitSetTest.cpp @@ -41,6 +41,10 @@ TEST(BitSet, Count) { const auto bitset = BitSet32(number); EXPECT_EQ(bitset.Count(), bitcount); + u32 iterating_count = 0; + for (auto iter = bitset.begin(); iter != bitset.end(); ++iter) + ++iterating_count; + EXPECT_EQ(iterating_count, bitcount); } constexpr std::array, 9> random_64bit_number_bitcount_pairs = { @@ -57,6 +61,10 @@ TEST(BitSet, Count) { const auto bitset = BitSet64(number); EXPECT_EQ(bitset.Count(), bitcount); + u32 iterating_count = 0; + for (auto iter = bitset.begin(); iter != bitset.end(); ++iter) + ++iterating_count; + EXPECT_EQ(iterating_count, bitcount); } }