Skip to content

Commit fe7b6a9

Browse files
committed
fix truncate and sign_extend for size == 0
1 parent aad13a1 commit fe7b6a9

File tree

1 file changed

+16
-0
lines changed
  • src/librustc/mir/interpret

1 file changed

+16
-0
lines changed

src/librustc/mir/interpret/mod.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ impl<'tcx> AllocMap<'tcx> {
349349
/// illegal and will likely ICE.
350350
/// This function exists to allow const eval to detect the difference between evaluation-
351351
/// local dangling pointers and allocations in constants/statics.
352+
#[inline]
352353
pub fn get(&self, id: AllocId) -> Option<AllocKind<'tcx>> {
353354
self.id_to_kind.get(&id).cloned()
354355
}
@@ -397,6 +398,7 @@ impl<'tcx> AllocMap<'tcx> {
397398
// Methods to access integers in the target endianness
398399
////////////////////////////////////////////////////////////////////////////////
399400

401+
#[inline]
400402
pub fn write_target_uint(
401403
endianness: layout::Endian,
402404
mut target: &mut [u8],
@@ -409,6 +411,7 @@ pub fn write_target_uint(
409411
}
410412
}
411413

414+
#[inline]
412415
pub fn read_target_uint(endianness: layout::Endian, mut source: &[u8]) -> Result<u128, io::Error> {
413416
match endianness {
414417
layout::Endian::Little => source.read_uint128::<LittleEndian>(source.len()),
@@ -420,17 +423,30 @@ pub fn read_target_uint(endianness: layout::Endian, mut source: &[u8]) -> Result
420423
// Methods to facilitate working with signed integers stored in a u128
421424
////////////////////////////////////////////////////////////////////////////////
422425

426+
/// Truncate `value` to `size` bits and then sign-extend it to 128 bits
427+
/// (i.e., if it is negative, fill with 1's on the left).
428+
#[inline]
423429
pub fn sign_extend(value: u128, size: Size) -> u128 {
424430
let size = size.bits();
431+
if size == 0 {
432+
// Truncated until nothing is left.
433+
return 0;
434+
}
425435
// sign extend
426436
let shift = 128 - size;
427437
// shift the unsigned value to the left
428438
// and back to the right as signed (essentially fills with FF on the left)
429439
(((value << shift) as i128) >> shift) as u128
430440
}
431441

442+
/// Truncate `value` to `size` bits.
443+
#[inline]
432444
pub fn truncate(value: u128, size: Size) -> u128 {
433445
let size = size.bits();
446+
if size == 0 {
447+
// Truncated until nothing is left.
448+
return 0;
449+
}
434450
let shift = 128 - size;
435451
// truncate (shift left to drop out leftover values, shift right to fill with zeroes)
436452
(value << shift) >> shift

0 commit comments

Comments
 (0)