Skip to content

Commit 44a360d

Browse files
authored
Merge pull request rust-lang#316 from solson/priroda
Fix relocation copying in overlapping copies
2 parents b93462a + 385b5b9 commit 44a360d

File tree

4 files changed

+38
-28
lines changed

4 files changed

+38
-28
lines changed

miri/lib.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,8 @@
66
// From rustc.
77
#[macro_use]
88
extern crate log;
9-
extern crate log_settings;
109
#[macro_use]
1110
extern crate rustc;
12-
extern crate rustc_const_math;
13-
extern crate rustc_data_structures;
1411
extern crate syntax;
1512

1613
use rustc::ty::{self, TyCtxt};
@@ -146,9 +143,9 @@ pub fn eval_main<'a, 'tcx: 'a>(
146143
}
147144
}
148145

149-
struct Evaluator;
146+
pub struct Evaluator;
150147
#[derive(Default)]
151-
struct EvaluatorData {
148+
pub struct EvaluatorData {
152149
/// Environment variables set by `setenv`
153150
/// Miri does not expose env vars from the host to the emulated program
154151
pub(crate) env_vars: HashMap<Vec<u8>, MemoryPointer>,
@@ -163,7 +160,7 @@ pub struct TlsEntry<'tcx> {
163160
}
164161

165162
#[derive(Default)]
166-
struct MemoryData<'tcx> {
163+
pub struct MemoryData<'tcx> {
167164
/// The Key to use for the next thread-local allocation.
168165
next_thread_local: TlsKey,
169166

src/librustc_mir/interpret/memory.rs

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ impl LockInfo {
7979
pub struct AllocId(u64);
8080

8181
#[derive(Debug)]
82-
enum AllocIdKind {
82+
pub enum AllocIdKind {
8383
/// We can't ever have more than `usize::max_value` functions at the same time
8484
/// since we never "deallocate" functions
8585
Function(usize),
@@ -89,7 +89,7 @@ enum AllocIdKind {
8989
}
9090

9191
impl AllocIdKind {
92-
fn into_alloc_id(self) -> AllocId {
92+
pub fn into_alloc_id(self) -> AllocId {
9393
match self {
9494
AllocIdKind::Function(n) => AllocId(n as u64),
9595
AllocIdKind::Runtime(n) => AllocId((1 << 63) | n),
@@ -103,10 +103,10 @@ impl AllocId {
103103
self.0 >> 63
104104
}
105105
/// Yields everything but the discriminant bits
106-
fn index(self) -> u64 {
106+
pub fn index(self) -> u64 {
107107
self.0 & ((1 << 63) - 1)
108108
}
109-
fn into_alloc_id_kind(self) -> AllocIdKind {
109+
pub fn into_alloc_id_kind(self) -> AllocIdKind {
110110
match self.discriminant() {
111111
0 => AllocIdKind::Function(self.index() as usize),
112112
1 => AllocIdKind::Runtime(self.index()),
@@ -1088,6 +1088,17 @@ impl<'a, 'tcx, M: Machine<'tcx>> Memory<'a, 'tcx, M> {
10881088
let dest = dest.to_ptr()?;
10891089
self.check_relocation_edges(src, size)?;
10901090

1091+
// first copy the relocations to a temporary buffer, because
1092+
// `get_bytes_mut` will clear the relocations, which is correct,
1093+
// since we don't want to keep any relocations at the target.
1094+
1095+
let relocations: Vec<_> = self.relocations(src, size)?
1096+
.map(|(&offset, &alloc_id)| {
1097+
// Update relocation offsets for the new positions in the destination allocation.
1098+
(offset + dest.offset - src.offset, alloc_id)
1099+
})
1100+
.collect();
1101+
10911102
let src_bytes = self.get_bytes_unchecked(src, size, align)?.as_ptr();
10921103
let dest_bytes = self.get_bytes_mut(dest, size, align)?.as_mut_ptr();
10931104

@@ -1113,7 +1124,8 @@ impl<'a, 'tcx, M: Machine<'tcx>> Memory<'a, 'tcx, M> {
11131124
}
11141125

11151126
self.copy_undef_mask(src, dest, size)?;
1116-
self.copy_relocations(src, dest, size)?;
1127+
// copy back the relocations
1128+
self.get_mut(dest.alloc_id)?.relocations.extend(relocations);
11171129

11181130
Ok(())
11191131
}
@@ -1388,22 +1400,6 @@ impl<'a, 'tcx, M: Machine<'tcx>> Memory<'a, 'tcx, M> {
13881400
}
13891401
Ok(())
13901402
}
1391-
1392-
fn copy_relocations(
1393-
&mut self,
1394-
src: MemoryPointer,
1395-
dest: MemoryPointer,
1396-
size: u64,
1397-
) -> EvalResult<'tcx> {
1398-
let relocations: Vec<_> = self.relocations(src, size)?
1399-
.map(|(&offset, &alloc_id)| {
1400-
// Update relocation offsets for the new positions in the destination allocation.
1401-
(offset + dest.offset - src.offset, alloc_id)
1402-
})
1403-
.collect();
1404-
self.get_mut(dest.alloc_id)?.relocations.extend(relocations);
1405-
Ok(())
1406-
}
14071403
}
14081404

14091405
/// Undefined bytes

src/librustc_mir/interpret/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ pub use self::eval_context::{EvalContext, Frame, ResourceLimits, StackPopCleanup
2727

2828
pub use self::lvalue::{Lvalue, LvalueExtra, GlobalId};
2929

30-
pub use self::memory::{AllocId, Memory, MemoryPointer, MemoryKind, HasMemory};
30+
pub use self::memory::{AllocId, Memory, MemoryPointer, MemoryKind, HasMemory, AllocIdKind};
3131

3232
use self::memory::{PointerArithmetic, Lock, AccessKind};
3333

tests/run-pass/btreemap.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// mir validation can't cope with `mem::uninitialized::<SomeEnum>()`
2+
// compile-flags: -Zmir-emit-validate=0
3+
4+
#[derive(PartialEq, Eq, PartialOrd, Ord)]
5+
pub enum Foo {
6+
A(&'static str),
7+
_B,
8+
_C,
9+
}
10+
11+
pub fn main() {
12+
let mut b = std::collections::BTreeSet::new();
13+
b.insert(Foo::A("\'"));
14+
b.insert(Foo::A("/="));
15+
b.insert(Foo::A("#"));
16+
b.insert(Foo::A("0o"));
17+
}

0 commit comments

Comments
 (0)