Skip to content

Commit 3aa1122

Browse files
committed
auto merge of #6461 : thestinger/rust/fix_priority_queue, r=pcwalton
uninit() would result in potentially running a destructor on arbitrary memory if the Ord implementation throws
2 parents 62640f5 + e1a1992 commit 3aa1122

File tree

1 file changed

+4
-56
lines changed

1 file changed

+4
-56
lines changed

src/libstd/priority_queue.rs

+4-56
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,7 @@
1212
1313
use core::old_iter::BaseIter;
1414
use core::util::{replace, swap};
15-
16-
#[abi = "rust-intrinsic"]
17-
extern "rust-intrinsic" {
18-
fn move_val_init<T>(dst: &mut T, src: T);
19-
fn init<T>() -> T;
20-
#[cfg(not(stage0))]
21-
fn uninit<T>() -> T;
22-
}
15+
use core::unstable::intrinsics::{init, move_val_init};
2316

2417
pub struct PriorityQueue<T> {
2518
priv data: ~[T],
@@ -141,33 +134,13 @@ pub impl <T:Ord> PriorityQueue<T> {
141134

142135
// The implementations of siftup and siftdown use unsafe blocks in
143136
// order to move an element out of the vector (leaving behind a
144-
// junk element), shift along the others and move it back into the
137+
// zeroed element), shift along the others and move it back into the
145138
// vector over the junk element. This reduces the constant factor
146139
// compared to using swaps, which involves twice as many moves.
147140

148-
#[cfg(not(stage0))]
149-
priv fn siftup(&mut self, start: uint, mut pos: uint) {
150-
unsafe {
151-
let new = *ptr::to_unsafe_ptr(&self.data[pos]);
152-
153-
while pos > start {
154-
let parent = (pos - 1) >> 1;
155-
if new > self.data[parent] {
156-
let x = replace(&mut self.data[parent], uninit());
157-
move_val_init(&mut self.data[pos], x);
158-
pos = parent;
159-
loop
160-
}
161-
break
162-
}
163-
move_val_init(&mut self.data[pos], new);
164-
}
165-
}
166-
167-
#[cfg(stage0)]
168141
priv fn siftup(&mut self, start: uint, mut pos: uint) {
169142
unsafe {
170-
let new = *ptr::to_unsafe_ptr(&self.data[pos]);
143+
let new = replace(&mut self.data[pos], init());
171144

172145
while pos > start {
173146
let parent = (pos - 1) >> 1;
@@ -183,35 +156,10 @@ pub impl <T:Ord> PriorityQueue<T> {
183156
}
184157
}
185158

186-
187-
#[cfg(not(stage0))]
188-
priv fn siftdown_range(&mut self, mut pos: uint, end: uint) {
189-
unsafe {
190-
let start = pos;
191-
let new = *ptr::to_unsafe_ptr(&self.data[pos]);
192-
193-
let mut child = 2 * pos + 1;
194-
while child < end {
195-
let right = child + 1;
196-
if right < end && !(self.data[child] > self.data[right]) {
197-
child = right;
198-
}
199-
let x = replace(&mut self.data[child], uninit());
200-
move_val_init(&mut self.data[pos], x);
201-
pos = child;
202-
child = 2 * pos + 1;
203-
}
204-
205-
move_val_init(&mut self.data[pos], new);
206-
self.siftup(start, pos);
207-
}
208-
}
209-
210-
#[cfg(stage0)]
211159
priv fn siftdown_range(&mut self, mut pos: uint, end: uint) {
212160
unsafe {
213161
let start = pos;
214-
let new = *ptr::to_unsafe_ptr(&self.data[pos]);
162+
let new = replace(&mut self.data[pos], init());
215163

216164
let mut child = 2 * pos + 1;
217165
while child < end {

0 commit comments

Comments
 (0)