Skip to content

Commit

Permalink
Fix broken left shift of IV_MIN under 'use integer'
Browse files Browse the repository at this point in the history
This fixes GH 18639

When I wrote this code, I conflated casting and complementing.
  • Loading branch information
khwilliamson authored and Max Maischein committed Jun 20, 2021
1 parent ae065a1 commit 2ca358e
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 4 deletions.
3 changes: 0 additions & 3 deletions pp.c
Original file line number Diff line number Diff line change
Expand Up @@ -2007,9 +2007,6 @@ static IV S_iv_shift(IV iv, int shift, bool left)
* 18446744073709551552
* */
if (left) {
if (iv == IV_MIN) { /* Casting this to a UV is undefined behavior */
return 0;
}
return (IV) (((UV) iv) << shift);
}

Expand Down
9 changes: 8 additions & 1 deletion t/op/bop.t
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ BEGIN {
# If you find tests are failing, please try adding names to tests to track
# down where the failure is, and supply your new names as a patch.
# (Just-in-time test naming)
plan tests => 502;
plan tests => 503;

# numerics
ok ((0xdead & 0xbeef) == 0x9ead);
Expand All @@ -33,6 +33,13 @@ ok ((33023 >> 7) == 257);
# signed vs. unsigned
ok ((~0 > 0 && do { use integer; ~0 } == -1));

{ # GH #18639
my $iv_min = -(~0 >> 1) - 1;
my $shifted;
{ use integer; $shifted = $iv_min << 0 };
is($shifted, $iv_min, "IV_MIN << 0 yields IV_MIN under 'use integer'");
}

my $bits = 0;
for (my $i = ~0; $i; $i >>= 1) { ++$bits; }
my $cusp = 1 << ($bits - 1);
Expand Down

0 comments on commit 2ca358e

Please sign in to comment.