Commit 4f49b8a2 authored by Anton Bikineev's avatar Anton Bikineev Committed by V8 LUCI CQ

cppgc: Fix undefined behaviour when decompressing

Shifting negative integrals is undefined behavior. The CL simply
switches to uint64_t when decompressing, which anyway results in
sign-extension (in standard terms, integral promotion must preserve the
value and the sign of the source operand).

The CL doesn't have any functional changes, the generated code is the
same. It only fixes the ubsan report.

Bug: chromium:1325007
Change-Id: I491a87b84d4e98b0225f76825dac2f9e85f168d1
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3736442
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Auto-Submit: Anton Bikineev <bikineev@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81452}
parent c00444b9
......@@ -121,8 +121,10 @@ class CompressedPointer final {
static V8_INLINE void* Decompress(Storage ptr) {
CPPGC_DCHECK(CageBaseGlobal::IsSet());
const uintptr_t base = CageBaseGlobal::Get();
// Sign extend the pointer and shift left by one.
const int64_t mask = static_cast<int64_t>(static_cast<int32_t>(ptr)) << 1;
// Treat compressed pointer as signed and cast it to uint64_t, which will
// sign-extend it. Then, shift the result by one. It's important to shift
// the unsigned value, as otherwise it would result in undefined behavior.
const uint64_t mask = static_cast<uint64_t>(static_cast<int32_t>(ptr)) << 1;
return reinterpret_cast<void*>(mask & base);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment