about summary refs log tree commit diff
path: root/compiler/rustc_middle/src
diff options
context:
space:
mode:
author许杰友 Jieyou Xu (Joe) <39484203+jieyouxu@users.noreply.github.com>2024-06-11 14:16:47 +0100
committerGitHub <noreply@github.com>2024-06-11 14:16:47 +0100
commitcfd48bdd7e124565de8022f8b87ef5a3aa7f78cd (patch)
tree569c4ba9fde857fd201ec0729b3f7048ddb0051a /compiler/rustc_middle/src
parent2a94a5bc218c6af1667a856f9fee1fdfe892fdc7 (diff)
parentde4ac0c465facfdfd56ce08dc6bb5cfee901561c (diff)
Rollup merge of #126265 - RalfJung:interpret-cast-validity, r=oli-obk
interpret: ensure we check bool/char for validity when they are used in a cast

In general, `Scalar::to_bits` is a bit dangerous as it bypasses all type information. We should usually prefer matching on the type and acting according to that. So I also refactored `unary_op` handling of integers to do that. The remaining `to_bits` uses are operations that just fundamentally don't care about the sign (and only work on integers).

invalid_char_cast.rs is the key new test, the others already passed before this PR.

r? `@oli-obk`
Diffstat (limited to 'compiler/rustc_middle/src')
-rw-r--r--compiler/rustc_middle/src/ty/consts/int.rs15
1 files changed, 5 insertions, 10 deletions
diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs
index 52320dd141b..13691b61941 100644
--- a/compiler/rustc_middle/src/ty/consts/int.rs
+++ b/compiler/rustc_middle/src/ty/consts/int.rs
@@ -209,8 +209,8 @@ impl ScalarInt {
 
     #[inline]
     pub fn try_from_uint(i: impl Into<u128>, size: Size) -> Option<Self> {
-        let data = i.into();
-        if size.truncate(data) == data { Some(Self::raw(data, size)) } else { None }
+        let (r, overflow) = Self::truncate_from_uint(i, size);
+        if overflow { None } else { Some(r) }
     }
 
     /// Returns the truncated result, and whether truncation changed the value.
@@ -223,20 +223,15 @@ impl ScalarInt {
 
     #[inline]
     pub fn try_from_int(i: impl Into<i128>, size: Size) -> Option<Self> {
-        let i = i.into();
-        // `into` performed sign extension, we have to truncate
-        let truncated = size.truncate(i as u128);
-        if size.sign_extend(truncated) as i128 == i {
-            Some(Self::raw(truncated, size))
-        } else {
-            None
-        }
+        let (r, overflow) = Self::truncate_from_int(i, size);
+        if overflow { None } else { Some(r) }
     }
 
     /// Returns the truncated result, and whether truncation changed the value.
     #[inline]
     pub fn truncate_from_int(i: impl Into<i128>, size: Size) -> (Self, bool) {
         let data = i.into();
+        // `into` performed sign extension, we have to truncate
         let r = Self::raw(size.truncate(data as u128), size);
         (r, size.sign_extend(r.data) as i128 != data)
     }