Skip to content

Commit 5fff1d7

Browse files
authored
Rollup merge of #91162 - RalfJung:miri-shift-truncation, r=oli-obk
explain why CTFE/Miri perform truncation on shift offset Closes rust-lang/miri#1920
2 parents 5f6cb2c + 5f6ccf6 commit 5fff1d7

File tree

2 files changed

+14
-1
lines changed

2 files changed

+14
-1
lines changed

compiler/rustc_const_eval/src/interpret/operator.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
130130
let signed = left_layout.abi.is_signed();
131131
let size = u128::from(left_layout.size.bits());
132132
let overflow = r >= size;
133-
let r = r % size; // mask to type size
133+
// The shift offset is implicitly masked to the type size, to make sure this operation
134+
// is always defined. This is the one MIR operator that does *not* directly map to a
135+
// single LLVM operation. See
136+
// <https://github.com/rust-lang/rust/blob/a3b9405ae7bb6ab4e8103b414e75c44598a10fd2/compiler/rustc_codegen_ssa/src/common.rs#L131-L158>
137+
// for the corresponding truncation in our codegen backends.
138+
let r = r % size;
134139
let r = u32::try_from(r).unwrap(); // we masked so this will always fit
135140
let result = if signed {
136141
let l = self.sign_extend(l, left_layout) as i128;

compiler/rustc_middle/src/mir/mod.rs

+8
Original file line numberDiff line numberDiff line change
@@ -2246,8 +2246,12 @@ pub enum BinOp {
22462246
/// The `*` operator (multiplication)
22472247
Mul,
22482248
/// The `/` operator (division)
2249+
///
2250+
/// Division by zero is UB.
22492251
Div,
22502252
/// The `%` operator (modulus)
2253+
///
2254+
/// Using zero as the modulus (second operand) is UB.
22512255
Rem,
22522256
/// The `^` operator (bitwise xor)
22532257
BitXor,
@@ -2256,8 +2260,12 @@ pub enum BinOp {
22562260
/// The `|` operator (bitwise or)
22572261
BitOr,
22582262
/// The `<<` operator (shift left)
2263+
///
2264+
/// The offset is truncated to the size of the first operand before shifting.
22592265
Shl,
22602266
/// The `>>` operator (shift right)
2267+
///
2268+
/// The offset is truncated to the size of the first operand before shifting.
22612269
Shr,
22622270
/// The `==` operator (equality)
22632271
Eq,

0 commit comments

Comments
 (0)