about summary refs log tree commit diff
diff options
context:
space:
mode:
authorhkalbasi <hamidrezakalbasi@protonmail.com>2023-07-01 17:16:56 +0330
committerhkalbasi <hamidrezakalbasi@protonmail.com>2023-07-01 17:16:56 +0330
commit15a0da6f3087a0248fb8b62dac49b24fd287afd9 (patch)
treebdd4f601c718454d0ea2865eaefb103a325c328f
parentbb85a980e022b1b19d4b8e5166bd2d529f55ef48 (diff)
downloadrust-15a0da6f3087a0248fb8b62dac49b24fd287afd9.tar.gz
rust-15a0da6f3087a0248fb8b62dac49b24fd287afd9.zip
Fix overflow checking in shift operator
-rw-r--r--crates/hir-ty/src/consteval/tests.rs1
-rw-r--r--crates/hir-ty/src/mir/eval.rs7
2 files changed, 7 insertions, 1 deletions
diff --git a/crates/hir-ty/src/consteval/tests.rs b/crates/hir-ty/src/consteval/tests.rs
index e50dfdf965e..9baedc3fb74 100644
--- a/crates/hir-ty/src/consteval/tests.rs
+++ b/crates/hir-ty/src/consteval/tests.rs
@@ -108,6 +108,7 @@ fn bit_op() {
     check_fail(r#"const GOAL: i8 = 1 << 8"#, |e| {
         e == ConstEvalError::MirEvalError(MirEvalError::Panic("Overflow in Shl".to_string()))
     });
+    check_number(r#"const GOAL: i32 = 100000000i32 << 11"#, (100000000i32 << 11) as i128);
 }
 
 #[test]
diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs
index dd23f1957c7..1c528820721 100644
--- a/crates/hir-ty/src/mir/eval.rs
+++ b/crates/hir-ty/src/mir/eval.rs
@@ -1037,13 +1037,18 @@ impl Evaluator<'_> {
                                         BinOp::Shr => l128.checked_shr(shift_amount),
                                         _ => unreachable!(),
                                     };
+                                    if shift_amount as usize >= lc.len() * 8 {
+                                        return Err(MirEvalError::Panic(format!(
+                                            "Overflow in {op:?}"
+                                        )));
+                                    }
                                     if let Some(r) = r {
                                         break 'b r;
                                     }
                                 };
                                 return Err(MirEvalError::Panic(format!("Overflow in {op:?}")));
                             };
-                            check_overflow(r)?
+                            Owned(r.to_le_bytes()[..lc.len()].to_vec())
                         }
                         BinOp::Offset => not_supported!("offset binop"),
                     }