Fix UB when hashing some doubles in 32bits. #1680
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
In 32 bits platforms, for some doubles the hash result could be
incorrectly zero (or whatever undefined behaviour happens to be).
The problem happens when the non fractional part of the double is high
and the fractional part is between 0 and 0.5 and high enough to make the
sum of both not fit into 32 bits. In that case, the use of += promotes
result to double to add it to the fractional double, but when it gets
converted back into CFHashCode, since it is outside the 32 bit range, it
might end up as zero.
Casting fractional to CFHashCode avoids the hidden promotion, and should
not fail, since fractional is at most ULONG_MAX/2.
The problem doesn't exist in 64 bits, since CFHashCode is 64 bits wide
there.