Fixed macro hash_vec(vec): it was checking only the first bytes (4 or 8, not sure) (#2718)

* Fixed macro hash_vec(vec): it was checking only 8 bytes

* use $sizeof() directly as it is correct now

* Added unit test for vector types

Tests that hashes match for same values and that they don't match
when changing a single bit on any of the vector elements

* Changed hardcoded value for the compiler option

* Release note

---------

Co-authored-by: Christoffer Lerno <christoffer@aegik.com>
This commit is contained in:
mikelgarai
2026-01-14 23:22:10 +01:00
committed by GitHub
parent 0a9d4e398d
commit cd4c586c3f
3 changed files with 59 additions and 1 deletions

View File

@@ -700,7 +700,7 @@ macro uint hash_array(array_ptr) @local
*>
macro uint hash_vec(vec) @local
{
var $len = $sizeof(vec.len * $typeof(vec).inner.sizeof);
var $len = $sizeof(vec);
$if $len > 16:
return (uint)komi::hash(((char*)&&vec)[:$len]);

View File

@@ -58,6 +58,7 @@
- Creating recursive debug info for functions could cause assertions.
- bitorder::read and bitorder::write may fail because of unaligned access #2734.
- Fix `LinkedList.to_format` to properly iterate linked list for printing.
- Hashing a vector would not use the entire vector in some cases.
### Stdlib changes
- Add `ThreadPool` join function to wait for all threads to finish in the pool without destroying the threads.

View File

@@ -174,6 +174,63 @@ fn void test_hash_repeat()
assert(int.typeid.hash() == int.typeid.hash());
}
macro test_hash_vector_macro(...)
{
int[] $lens = {1, 2, 4, 7, 8, 13, 16, 23, 32, 43, 64, 103};
$for var $i = 0; $i < $vacount ; $i++:
{
$foreach $vec_len : $lens:
{
$if $vec_len * $vatype[$i].sizeof * 8 <= $$MAX_VECTOR_SIZE:
{
$vatype[$i][<$vec_len>] vec1, vec2;
for (int val = 0; val < $vec_len; val++)
{
$vatype[$i] tval = ($vatype[$i])val;
vec1[val] = (tval | (tval << (($vatype[$i].sizeof - 1) * 8)));
}
vec2 = vec1;
assert(vec1.hash() == vec2.hash(), "hashes don't match for %s and %s", vec1, vec2);
for (int val = 0; val < $vec_len; val++)
{
vec2[val] ^= (($vatype[$i])0b0010_0000 << (($vatype[$i].sizeof - 1) * 8));
assert(vec1.hash() != vec2.hash(), "hashes match for %s and %s", vec1, vec2);
vec2[val] ^= (($vatype[$i])0b0010_0000 << (($vatype[$i].sizeof - 1) * 8));
}
}
$endif
}
$endforeach
}
$endfor
}
macro test_hash_vector_macro_bool()
{
int[] $lens = {1, 2, 4, 7, 8, 13, 16, 23, 32, 43, 64, 103};
$foreach $vec_len : $lens:
{
bool[<$vec_len>] vec1, vec2;
for (int val = 0; val < $vec_len; val++)
{
vec1[val] = ((val & 0x3) == 0);
}
vec2 = vec1;
assert(vec1.hash() == vec2.hash(), "hashes don't match for %s and %s", vec1, vec2);
for (int val = 0; val < $vec_len; val++)
{
vec2[val] = !vec2[val];
assert(vec1.hash() != vec2.hash(), "hashes match for %s and %s", vec1, vec2);
vec2[val] = !vec2[val];
}
}
$endforeach
}
fn void test_hash_vector()
{
test_hash_vector_macro(char, ichar, short, ushort, int, uint, long, ulong, int128, uint128);
test_hash_vector_macro_bool();
}
fn void test_builtin_string_hashing() => @pool()
{
var $x = "";