RFR: 5038439: Warning message for literal shift amounts outside the canonical domain

Raffaello Giulietti rgiulietti at openjdk.org
Mon Nov 3 18:12:13 UTC 2025


On Mon, 3 Nov 2025 16:47:56 GMT, Jan Lahoda <jlahoda at openjdk.org> wrote:

>> When bit shifting an `int` or `long` value by an amount `X`, all but the last 5 or 6 (respectively) bits of `X` are ignored.
>> 
>> This can create a trap for the unwary, as in this example:
>> 
>> public long readLongBigEndian(byte[] buf, int offset) {
>>     return ((buf[offset + 0] & 0xff) << 56)   // BUG HERE
>>          | ((buf[offset + 1] & 0xff) << 48)   // BUG HERE
>>          | ((buf[offset + 2] & 0xff) << 40)   // BUG HERE
>>          | ((buf[offset + 3] & 0xff) << 32)   // BUG HERE
>>          | ((buf[offset + 4] & 0xff) << 24)
>>          | ((buf[offset + 5] & 0xff) << 16)
>>          | ((buf[offset + 6] & 0xff) << 8)
>>          | ((buf[offset + 7] & 0xff);
>> }
>> 
>> This PR adds a new warning when the compiler detects an out-of-range bit shift, i.e., an `int` bit shift not in the range `[0...31]` or a `long` bit shift not in the range `[0...63]`.
>
> test/langtools/tools/javac/lint/ShiftOutOfRange.java line 14:
> 
>> 12: 
>> 13:         // These should generate warnings
>> 14:         a = a << (byte)-1;
> 
> Looking at the patch, I am not completely convinced disallowing `-1` is beneficial. On one hand, it looks weird. On the other hand, it makes some sense (as far as I can tell, it is universal for both `int` and `long`). And, unlike `128`, it is not clearly wrong. I am not sure if it wouldn't be better to simply permit `-1` as a special case.
> 
> I see there are `<< -5` in the microbenchmark tests, but I think I am less inclined to accommodate negative values other than `-1`, as the semantics of those is much more cryptic, for me at least.
> 
> Please let me know what you think.

One way to read `v << -n` is: "Shift out everything to the left, except for the `n` least significant bits".
Analogously for `v >>> -n`: "Shift out everything to the right, except for the `n` most significant bits".

To rotate `v` by `n` bits to the left, for example, one can write `v << n | v >>> -n` (regardless of the width of `v`)

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/27102#discussion_r2487416183


More information about the compiler-dev mailing list