Skip to content

Commit 0d5ea84

Browse files
committed
FIX: Add AbortIfPanic guard to remove_index
It's a critical section where we can't panic. Mark the reason in the guard and message.
1 parent 107f51f commit 0d5ea84

File tree

3 files changed

+44
-0
lines changed

3 files changed

+44
-0
lines changed

src/impl_methods.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use crate::dimension::broadcast::co_broadcast;
2626
use crate::error::{self, ErrorKind, ShapeError, from_kind};
2727
use crate::math_cell::MathCell;
2828
use crate::itertools::zip;
29+
use crate::low_level_util::AbortIfPanic;
2930
use crate::zip::{IntoNdProducer, Zip};
3031
use crate::AxisDescription;
3132

@@ -2476,6 +2477,7 @@ where
24762477
// dst = elt;
24772478
// }
24782479
//
2480+
let guard = AbortIfPanic(&"remove_index: temporarily moving out of owned value");
24792481
let mut slot = MaybeUninit::<A>::uninit();
24802482
unsafe {
24812483
slot.as_mut_ptr().copy_from_nonoverlapping(dst, 1);
@@ -2485,6 +2487,7 @@ where
24852487
}
24862488
(dst as *mut A).copy_from_nonoverlapping(slot.as_ptr(), 1);
24872489
}
2490+
guard.defuse();
24882491
});
24892492
// then slice the axis in place to cut out the removed final element
24902493
self.slice_axis_inplace(axis, Slice::new(0, Some(-1), 1));

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ mod shape_builder;
205205
mod slice;
206206
mod split_at;
207207
mod stacking;
208+
mod low_level_util;
208209
#[macro_use]
209210
mod zip;
210211

src/low_level_util.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright 2021 bluss and ndarray developers.
2+
//
3+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6+
// option. This file may not be copied, modified, or distributed
7+
// except according to those terms.
8+
9+
10+
/// Guard value that will abort if it is dropped.
11+
/// To defuse, this value must be forgotten before the end of the scope.
12+
///
13+
/// The string value is added to the message printed if aborting.
14+
#[must_use]
15+
pub(crate) struct AbortIfPanic(pub(crate) &'static &'static str);
16+
17+
impl AbortIfPanic {
18+
/// Defuse the AbortIfPanic guard. This *must* be done when finished.
19+
#[inline]
20+
pub(crate) fn defuse(self) {
21+
std::mem::forget(self);
22+
}
23+
}
24+
25+
impl Drop for AbortIfPanic {
26+
// The compiler should be able to remove this, if it can see through that there
27+
// is no panic in the code section.
28+
fn drop(&mut self) {
29+
#[cfg(feature="std")]
30+
{
31+
eprintln!("ndarray: panic in no-panic section, aborting: {}", self.0);
32+
std::process::abort()
33+
}
34+
#[cfg(not(feature="std"))]
35+
{
36+
// no-std uses panic-in-panic (should abort)
37+
panic!("ndarray: panic in no-panic section, bailing out: {}", self.0);
38+
}
39+
}
40+
}

0 commit comments

Comments
 (0)