RFR: 5038439: Warning message for literal shift amounts outside the canonical domain [v2]
Hannes Greule
hgreule at openjdk.org
Mon Nov 3 18:36:39 UTC 2025
On Mon, 3 Nov 2025 18:32:57 GMT, Archie Cobbs <acobbs 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]`.
>
> Archie Cobbs has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 10 commits:
>
> - Merge branch 'master' into JDK-5038439 to fix conflict.
> - Address review comment (combine switch cases).
> - Merge branch 'master' into JDK-5038439 to fix conflict.
> - Add "long" as a supported message parameter type.
> - Use "bit(s)" instead of "bits" where value could be 1.
> - Merge branch 'master' into JDK-5038439
> - Sprinkle more variety into the regression test.
> - Minor diff cleanup.
> - Update "lossy-conversions" description in compiler module Javadoc.
> - Warn for bit shifts using an out-of-range shift amount.
test/langtools/tools/javac/lint/ShiftOutOfRange.java line 18:
> 16: a = a >>> (short)-1;
> 17: a <<= -1;
> 18: a >>= -1L; // also generates "implicit cast from long to int in compound assignment is possibly lossy"
I'm a bit surprised by the additional warning here. The shift still operates on int, not long; i.e., unary promotion is performed for each argument rather than binary promotion https://docs.oracle.com/javase/specs/jls/se25/html/jls-15.html#jls-15.19
Should this be fixed (separately, obviously)?
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/27102#discussion_r2487472103
More information about the compiler-dev
mailing list