Skip to content

Commit a75e273

Browse files
Merge pull request #2044 from sahvx655-wq:bitshiftleft-signed-ub
PiperOrigin-RevId: 927408597
2 parents dd4f368 + e264932 commit a75e273

2 files changed

Lines changed: 7 additions & 1 deletion

File tree

extensions/math_ext.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,11 @@ Value BitShiftLeftInt(int64_t lhs, int64_t rhs) {
266266
if (rhs > 63) {
267267
return IntValue(0);
268268
}
269-
return IntValue(lhs << static_cast<int>(rhs));
269+
// Shift in the unsigned domain to avoid undefined behaviour when lhs is
270+
// negative or the shift moves bits into the sign bit, matching the bit
271+
// pattern semantics already used by bitShiftRight.
272+
return IntValue(absl::bit_cast<int64_t>(absl::bit_cast<uint64_t>(lhs)
273+
<< static_cast<int>(rhs)));
270274
}
271275

272276
Value BitShiftLeftUint(uint64_t lhs, int64_t rhs) {

extensions/math_ext_test.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,8 @@ INSTANTIATE_TEST_SUITE_P(
563563
{"math.bitNot(2) == -3"},
564564
{"math.bitAnd(math.bitNot(0x3u), 0xFFu) == 0xFCu"},
565565
{"math.bitShiftLeft(1, 1) == 2"},
566+
{"math.bitShiftLeft(-1, 1) == -2"},
567+
{"math.bitShiftLeft(-4, 2) == -16"},
566568
{"math.bitShiftLeft(1u, 1) == 2u"},
567569
{"math.bitShiftRight(4, 1) == 2"},
568570
{"math.bitShiftRight(4u, 1) == 2u"}}));

0 commit comments

Comments
 (0)