zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 135f4791e5cbffc75f51d404ef1abb6aca5de0e3 (tree)
parent 9e5869262a5f07300b7f4ff65dfe60810f22afee
Author: LemonBoy <thatlemon@gmail.com>
Date:   Thu, 17 Dec 2020 12:00:48 +0100

std: Don't hash undefined bits

auto_hash must be extra careful when hashing integers whose bit size is
not a multiple of 8 as, when reinterpreted with mem.asBytes, may contain
undefined non-zero bits too.

Diffstat:
Mlib/std/hash/auto_hash.zig | 11++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/lib/std/hash/auto_hash.zig b/lib/std/hash/auto_hash.zig @@ -99,7 +99,16 @@ pub fn hash(hasher: anytype, key: anytype, comptime strat: HashStrategy) void { // Help the optimizer see that hashing an int is easy by inlining! // TODO Check if the situation is better after #561 is resolved. - .Int => @call(.{ .modifier = .always_inline }, hasher.update, .{std.mem.asBytes(&key)}), + .Int => { + if (comptime meta.trait.hasUniqueRepresentation(Key)) { + @call(.{ .modifier = .always_inline }, hasher.update, .{std.mem.asBytes(&key)}); + } else { + // Take only the part containing the key value, the remaining + // bytes are undefined and must not be hashed! + const byte_size = comptime std.math.divCeil(comptime_int, @bitSizeOf(Key), 8) catch unreachable; + @call(.{ .modifier = .always_inline }, hasher.update, .{std.mem.asBytes(&key)[0..byte_size]}); + } + }, .Bool => hash(hasher, @boolToInt(key), strat), .Enum => hash(hasher, @enumToInt(key), strat),