Fixed undefined behavior in RNG.
We're basically trading undefined behavior for implementation defined behavior, which should be OK for UBSan. :-) The generated code should be identical, at least I checked that for GCC 4.6.3 on x64. BUG=377790 LOG=y R=dcarney@chromium.org Review URL: https://codereview.chromium.org/332733002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21828 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
817430f6ce
commit
ac18d08250
@ -117,7 +117,13 @@ void RandomNumberGenerator::NextBytes(void* buffer, size_t buflen) {
|
||||
int RandomNumberGenerator::Next(int bits) {
|
||||
ASSERT_LT(0, bits);
|
||||
ASSERT_GE(32, bits);
|
||||
int64_t seed = (seed_ * kMultiplier + kAddend) & kMask;
|
||||
// Do unsigned multiplication, which has the intended modulo semantics, while
|
||||
// signed multiplication would expose undefined behavior.
|
||||
uint64_t product = static_cast<uint64_t>(seed_) * kMultiplier;
|
||||
// Assigning a uint64_t to an int64_t is implementation defined, but this
|
||||
// should be OK. Use a static_cast to explicitly state that we know what we're
|
||||
// doing. (Famous last words...)
|
||||
int64_t seed = static_cast<int64_t>((product + kAddend) & kMask);
|
||||
seed_ = seed;
|
||||
return static_cast<int>(seed >> (48 - bits));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user