diff options
| author | bors <bors@rust-lang.org> | 2015-05-12 14:39:31 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-05-12 14:39:31 +0000 |
| commit | 2a5a320babdf000bc9cf719ccd9d95d250f83a02 (patch) | |
| tree | c38b76ac8c49fef76d19e0f6027ac676054afa7d /src/test | |
| parent | 0ad202671fc031ee90133fa5849ef0ec31164e04 (diff) | |
| parent | f2614f5858fed10e180102def32c60f180e46496 (diff) | |
| download | rust-2a5a320babdf000bc9cf719ccd9d95d250f83a02.tar.gz rust-2a5a320babdf000bc9cf719ccd9d95d250f83a02.zip | |
Auto merge of #25300 - kballard:core-slice-overflow, r=Gankro
core::slice was originally written to tolerate overflow (notably, with slices of zero-sized elements), but it was never updated to use wrapping arithmetic when overflow traps were added. Also correctly handle the case of calling .nth() on an Iter with a zero-sized element type. The iterator was assuming that the pointer value of the returned reference was meaningful, but that's not true for zero-sized elements. Fixes #25016.
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/run-pass/slice-of-zero-size-elements.rs | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/src/test/run-pass/slice-of-zero-size-elements.rs b/src/test/run-pass/slice-of-zero-size-elements.rs new file mode 100644 index 00000000000..6fe510586c7 --- /dev/null +++ b/src/test/run-pass/slice-of-zero-size-elements.rs @@ -0,0 +1,60 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -C debug-assertions + +#![feature(core)] + +use std::slice; + +fn foo<T>(v: &[T]) -> Option<&[T]> { + let mut it = v.iter(); + for _ in 0..5 { + let _ = it.next(); + } + Some(it.as_slice()) +} + +fn foo_mut<T>(v: &mut [T]) -> Option<&mut [T]> { + let mut it = v.iter_mut(); + for _ in 0..5 { + let _ = it.next(); + } + Some(it.into_slice()) +} + +pub fn main() { + // In a slice of zero-size elements the pointer is meaningless. + // Ensure iteration still works even if the pointer is at the end of the address space. + let slice: &[()] = unsafe { slice::from_raw_parts(-5isize as *const (), 10) }; + assert_eq!(slice.len(), 10); + assert_eq!(slice.iter().count(), 10); + + // .nth() on the iterator should also behave correctly + let mut it = slice.iter(); + assert!(it.nth(5).is_some()); + assert_eq!(it.count(), 4); + + // Converting Iter to a slice should never have a null pointer + assert!(foo(slice).is_some()); + + // Test mutable iterators as well + let slice: &mut [()] = unsafe { slice::from_raw_parts_mut(-5isize as *mut (), 10) }; + assert_eq!(slice.len(), 10); + assert_eq!(slice.iter_mut().count(), 10); + + { + let mut it = slice.iter_mut(); + assert!(it.nth(5).is_some()); + assert_eq!(it.count(), 4); + } + + assert!(foo_mut(slice).is_some()) +} |
