about summary refs log tree commit diff
diff options
context:
space:
mode:
authorhkalbasi <hamidrezakalbasi@protonmail.com>2023-06-29 17:28:05 +0330
committerhkalbasi <hamidrezakalbasi@protonmail.com>2023-06-29 17:28:48 +0330
commit22728033308028b2401e52b1bcb72d395a9aa6e4 (patch)
treeba43d246e33f7b9591584172a9d9bd9efa66b5c7
parentd7f4c2195084665e606b656f9061776e5a8d2953 (diff)
downloadrust-22728033308028b2401e52b1bcb72d395a9aa6e4.tar.gz
rust-22728033308028b2401e52b1bcb72d395a9aa6e4.zip
Fix realloc problem in allocating smaller amounts
-rw-r--r--crates/hir-ty/src/consteval/tests/intrinsics.rs1
-rw-r--r--crates/hir-ty/src/mir/eval/shim.rs16
2 files changed, 11 insertions, 6 deletions
diff --git a/crates/hir-ty/src/consteval/tests/intrinsics.rs b/crates/hir-ty/src/consteval/tests/intrinsics.rs
index ad64a455872..bb8fca178a2 100644
--- a/crates/hir-ty/src/consteval/tests/intrinsics.rs
+++ b/crates/hir-ty/src/consteval/tests/intrinsics.rs
@@ -183,6 +183,7 @@ fn allocator() {
             *ptr = 23;
             *ptr2 = 32;
             let ptr = __rust_realloc(ptr, 4, 1, 8);
+            let ptr = __rust_realloc(ptr, 8, 1, 3);
             let ptr2 = ((ptr as usize) + 1) as *mut u8;
             *ptr + *ptr2
         };
diff --git a/crates/hir-ty/src/mir/eval/shim.rs b/crates/hir-ty/src/mir/eval/shim.rs
index cab8f267b1e..23bb4a29f87 100644
--- a/crates/hir-ty/src/mir/eval/shim.rs
+++ b/crates/hir-ty/src/mir/eval/shim.rs
@@ -144,14 +144,18 @@ impl Evaluator<'_> {
                 let [ptr, old_size, align, new_size] = args else {
                     return Err(MirEvalError::TypeError("rustc_allocator args are not provided"));
                 };
-                let ptr = Address::from_bytes(ptr.get(self)?)?;
                 let old_size = from_bytes!(usize, old_size.get(self)?);
                 let new_size = from_bytes!(usize, new_size.get(self)?);
-                let align = from_bytes!(usize, align.get(self)?);
-                let result = self.heap_allocate(new_size, align);
-                Interval { addr: result, size: old_size }
-                    .write_from_interval(self, Interval { addr: ptr, size: old_size })?;
-                destination.write_from_bytes(self, &result.to_bytes())?;
+                if old_size >= new_size {
+                    destination.write_from_interval(self, ptr.interval)?;
+                } else {
+                    let ptr = Address::from_bytes(ptr.get(self)?)?;
+                    let align = from_bytes!(usize, align.get(self)?);
+                    let result = self.heap_allocate(new_size, align);
+                    Interval { addr: result, size: old_size }
+                        .write_from_interval(self, Interval { addr: ptr, size: old_size })?;
+                    destination.write_from_bytes(self, &result.to_bytes())?;
+                }
             }
             _ => not_supported!("unknown alloc function"),
         }