fix(timer): make the wrap-around top-bit test shift unsigned (1U << 31) - #97
Open
randomizedcoder wants to merge 1 commit into
Open
randomizedcoder wants to merge 1 commit into
randomizedcoder wants to merge 1 commit into
Conversation
homa_timer_check_rpc() decides whether to send NEED_ACK with a
wrap-around-safe comparison that tests the top bit of an unsigned
difference:
(rpc->done_timer_ticks + homa->request_ack_ticks
- 1 - homa->timer_ticks) & 1 << 31
`1 << 31` shifts a 1 into the sign bit of a signed int, which is
undefined behavior in C (the result isn't representable in int). Because
it's a constant expression the compiler folds it, so behavior happens to
be correct on gcc/x86 today, but it's UB on paper and a portability trap;
`-Wshift-overflow=2` flags it. Use `1U << 31` so the shift is well-defined
unsigned; the surrounding operands are already unsigned (u32 dominates the
expression), so the masked result is unchanged.
Verified: `-Wshift-overflow=2` warns at homa_timer.c:37 before and is
clean after; the timer unit suite stays green (10/10), including
homa_timer_check_rpc__request_ack whose tick sequence still emits
"xmit NEED_ACK".
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Bug: undefined
1 << 31in the NEED_ACK wrap-around testhoma_timer_check_rpc()uses a wrap-around-safe comparison to decide when to send aNEED_ACK, testing the top bit of an unsigned tick difference:1 << 31shifts a1into the sign bit of a signedint— the result (2³¹) isn't representable inint, which is undefined behavior in C.Because
1 << 31is a constant expression, the compiler folds it at compile time, so the runtime behavior is correct on gcc/x86 today (and UBSan's runtime shift check never sees it). It remains UB on paper and a portability trap, and-Wshift-overflow=2flags it.Fix
1U << 31is well-defined unsigned. The operands are already unsigned (done_timer_ticks/timer_ticksareu32, so the whole expression isunsigned int), so the masked value — the top bit of the wrap difference — is identical.Verification (compiler gate + regression)
-Wshift-overflow=2. The timer unit suite stays green (10/10);homa_timer_check_rpc__request_ackstill walks its tick sequence to"xmit NEED_ACK", confirming the behavior is unchanged.Note on the gate: the initial plan expected UBSan to catch this, but a constant-folded shift produces no runtime shift for UBSan to instrument — so the authoritative gate here is the compiler's
-Wshift-overflow=2, backed by the unchanged behavioral test.