Skip to content

Commit 7c1d7d8

Browse files
committed
---
yaml --- r: 129518 b: refs/heads/snap-stage3 c: 5ad7afc h: refs/heads/master v: v3
1 parent 877a2df commit 7c1d7d8

File tree

7 files changed

+228
-14
lines changed

7 files changed

+228
-14
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: 566b470e138e929e8a93d613372db1ba177c494f
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: 3e94401a6411001c7495a13dcbb289cb3935994f
4+
refs/heads/snap-stage3: 5ad7afc2d7e2671000f41a19bed73fef82475e47
55
refs/heads/try: 80b45ddbd351f0a4a939c3a3c4e20b4defec4b35
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/src/liballoc/heap.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ mod imp {
208208

209209
#[cfg(not(jemalloc), unix)]
210210
mod imp {
211+
use core::cmp;
211212
use core::mem;
212213
use core::ptr;
213214
use libc;
@@ -248,7 +249,7 @@ mod imp {
248249
pub unsafe fn reallocate(ptr: *mut u8, size: uint, align: uint,
249250
old_size: uint) -> *mut u8 {
250251
let new_ptr = allocate(size, align);
251-
ptr::copy_memory(new_ptr, ptr as *const u8, old_size);
252+
ptr::copy_memory(new_ptr, ptr as *const u8, cmp::min(size, old_size));
252253
deallocate(ptr, old_size, align);
253254
return new_ptr;
254255
}

branches/snap-stage3/src/libcore/str.rs

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1717,6 +1717,13 @@ pub trait StrSlice<'a> {
17171717
fn utf16_units(&self) -> Utf16CodeUnits<'a>;
17181718
}
17191719

1720+
#[inline(never)]
1721+
fn slice_error_fail(s: &str, begin: uint, end: uint) -> ! {
1722+
assert!(begin <= end);
1723+
fail!("index {} and/or {} in `{}` do not lie on character boundary",
1724+
begin, end, s);
1725+
}
1726+
17201727
impl<'a> StrSlice<'a> for &'a str {
17211728
#[inline]
17221729
fn contains<'a>(&self, needle: &'a str) -> bool {
@@ -1820,22 +1827,34 @@ impl<'a> StrSlice<'a> for &'a str {
18201827

18211828
#[inline]
18221829
fn slice(&self, begin: uint, end: uint) -> &'a str {
1823-
assert!(self.is_char_boundary(begin) && self.is_char_boundary(end),
1824-
"index {} and/or {} in `{}` do not lie on character boundary", begin,
1825-
end, *self);
1826-
unsafe { raw::slice_bytes(*self, begin, end) }
1830+
// is_char_boundary checks that the index is in [0, .len()]
1831+
if begin <= end &&
1832+
self.is_char_boundary(begin) &&
1833+
self.is_char_boundary(end) {
1834+
unsafe { raw::slice_unchecked(*self, begin, end) }
1835+
} else {
1836+
slice_error_fail(*self, begin, end)
1837+
}
18271838
}
18281839

18291840
#[inline]
18301841
fn slice_from(&self, begin: uint) -> &'a str {
1831-
self.slice(begin, self.len())
1842+
// is_char_boundary checks that the index is in [0, .len()]
1843+
if self.is_char_boundary(begin) {
1844+
unsafe { raw::slice_unchecked(*self, begin, self.len()) }
1845+
} else {
1846+
slice_error_fail(*self, begin, self.len())
1847+
}
18321848
}
18331849

18341850
#[inline]
18351851
fn slice_to(&self, end: uint) -> &'a str {
1836-
assert!(self.is_char_boundary(end), "index {} in `{}` does not lie on \
1837-
a character boundary", end, *self);
1838-
unsafe { raw::slice_bytes(*self, 0, end) }
1852+
// is_char_boundary checks that the index is in [0, .len()]
1853+
if self.is_char_boundary(end) {
1854+
unsafe { raw::slice_unchecked(*self, 0, end) }
1855+
} else {
1856+
slice_error_fail(*self, 0, end)
1857+
}
18391858
}
18401859

18411860
fn slice_chars(&self, begin: uint, end: uint) -> &'a str {
@@ -1910,9 +1929,10 @@ impl<'a> StrSlice<'a> for &'a str {
19101929
#[inline]
19111930
fn is_char_boundary(&self, index: uint) -> bool {
19121931
if index == self.len() { return true; }
1913-
if index > self.len() { return false; }
1914-
let b = self.as_bytes()[index];
1915-
return b < 128u8 || b >= 192u8;
1932+
match self.as_bytes().get(index) {
1933+
None => false,
1934+
Some(&b) => b < 128u8 || b >= 192u8,
1935+
}
19161936
}
19171937

19181938
#[inline]

branches/snap-stage3/src/librustc/back/link.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,13 @@ pub mod write {
536536
llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(builder, fpm);
537537
llvm::LLVMPassManagerBuilderPopulateModulePassManager(builder, mpm);
538538
llvm::LLVMPassManagerBuilderDispose(builder);
539+
540+
match opt {
541+
llvm::CodeGenLevelDefault | llvm::CodeGenLevelAggressive => {
542+
"mergefunc".with_c_str(|s| llvm::LLVMRustAddPass(mpm, s));
543+
}
544+
_ => {}
545+
};
539546
}
540547
}
541548

branches/snap-stage3/src/libstd/macros.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ macro_rules! fail(
9696
macro_rules! assert(
9797
($cond:expr) => (
9898
if !$cond {
99-
fail!("assertion failed: {:s}", stringify!($cond))
99+
fail!(concat!("assertion failed: ", stringify!($cond)))
100100
}
101101
);
102102
($cond:expr, $($arg:expr),+) => (
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
12+
// issues #10618 and #16382
13+
static SIZE: int = 25;
14+
15+
fn main() {
16+
let _a: [bool, ..1 as uint];
17+
let _b: [int, ..SIZE as uint] = [1, ..SIZE as uint];
18+
let _c: [bool, ..'\n' as uint] = [true, ..'\n' as uint];
19+
}
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// alloc::heap::reallocate test.
12+
//
13+
// Ideally this would be revised to use no_std, but for now it serves
14+
// well enough to reproduce (and illustrate) the bug from #16687.
15+
16+
extern crate alloc;
17+
18+
use alloc::heap;
19+
use std::ptr;
20+
21+
fn main() {
22+
unsafe {
23+
assert!(test_triangle());
24+
}
25+
}
26+
27+
unsafe fn test_triangle() -> bool {
28+
static COUNT : uint = 16;
29+
let mut ascend = Vec::from_elem(COUNT, ptr::mut_null());
30+
let ascend = ascend.as_mut_slice();
31+
static ALIGN : uint = 1;
32+
33+
// Checks that `ascend` forms triangle of acending size formed
34+
// from pairs of rows (where each pair of rows is equally sized),
35+
// and the elements of the triangle match their row-pair index.
36+
unsafe fn sanity_check(ascend: &[*mut u8]) {
37+
for i in range(0u, COUNT / 2) {
38+
let (p0, p1, size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
39+
for j in range(0u, size) {
40+
assert_eq!(*p0.offset(j as int), i as u8);
41+
assert_eq!(*p1.offset(j as int), i as u8);
42+
}
43+
}
44+
}
45+
46+
static PRINT : bool = false;
47+
48+
unsafe fn allocate(size: uint, align: uint) -> *mut u8 {
49+
if PRINT { println!("allocate(size={:u} align={:u})", size, align); }
50+
51+
let ret = heap::allocate(size, align);
52+
53+
if PRINT { println!("allocate(size={:u} align={:u}) ret: 0x{:010x}",
54+
size, align, ret as uint);
55+
}
56+
57+
ret
58+
}
59+
unsafe fn reallocate(ptr: *mut u8, size: uint, align: uint,
60+
old_size: uint) -> *mut u8 {
61+
if PRINT {
62+
println!("reallocate(ptr=0x{:010x} size={:u} align={:u} old_size={:u})",
63+
ptr as uint, size, align, old_size);
64+
}
65+
66+
let ret = heap::reallocate(ptr, size, align, old_size);
67+
68+
if PRINT {
69+
println!("reallocate(ptr=0x{:010x} size={:u} align={:u} old_size={:u}) \
70+
ret: 0x{:010x}",
71+
ptr as uint, size, align, old_size, ret as uint);
72+
}
73+
ret
74+
}
75+
76+
fn idx_to_size(i: uint) -> uint { (i+1) * 10 }
77+
78+
// Allocate pairs of rows that form a triangle shape. (Hope is
79+
// that at least two rows will be allocated near each other, so
80+
// that we trigger the bug (a buffer overrun) in an observable
81+
// way.)
82+
for i in range(0u, COUNT / 2) {
83+
let size = idx_to_size(i);
84+
ascend[2*i] = allocate(size, ALIGN);
85+
ascend[2*i+1] = allocate(size, ALIGN);
86+
}
87+
88+
// Initialize each pair of rows to distinct value.
89+
for i in range(0u, COUNT / 2) {
90+
let (p0, p1, size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
91+
for j in range(0, size) {
92+
*p0.offset(j as int) = i as u8;
93+
*p1.offset(j as int) = i as u8;
94+
}
95+
}
96+
97+
sanity_check(ascend.as_slice());
98+
test_1(ascend);
99+
test_2(ascend);
100+
test_3(ascend);
101+
test_4(ascend);
102+
103+
return true;
104+
105+
// Test 1: turn the triangle into a square (in terms of
106+
// allocation; initialized portion remains a triangle) by
107+
// realloc'ing each row from top to bottom, and checking all the
108+
// rows as we go.
109+
unsafe fn test_1(ascend: &mut [*mut u8]) {
110+
let new_size = idx_to_size(COUNT-1);
111+
for i in range(0u, COUNT / 2) {
112+
let (p0, p1, old_size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
113+
assert!(old_size < new_size);
114+
115+
ascend[2*i] = reallocate(p0, new_size, ALIGN, old_size);
116+
sanity_check(ascend.as_slice());
117+
118+
ascend[2*i+1] = reallocate(p1, new_size, ALIGN, old_size);
119+
sanity_check(ascend.as_slice());
120+
}
121+
}
122+
123+
// Test 2: turn the square back into a triangle, top to bottom.
124+
unsafe fn test_2(ascend: &mut [*mut u8]) {
125+
let old_size = idx_to_size(COUNT-1);
126+
for i in range(0u, COUNT / 2) {
127+
let (p0, p1, new_size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
128+
assert!(new_size < old_size);
129+
130+
ascend[2*i] = reallocate(p0, new_size, ALIGN, old_size);
131+
sanity_check(ascend.as_slice());
132+
133+
ascend[2*i+1] = reallocate(p1, new_size, ALIGN, old_size);
134+
sanity_check(ascend.as_slice());
135+
}
136+
}
137+
138+
// Test 3: turn triangle into a square, bottom to top.
139+
unsafe fn test_3(ascend: &mut [*mut u8]) {
140+
let new_size = idx_to_size(COUNT-1);
141+
for i in range(0u, COUNT / 2).rev() {
142+
let (p0, p1, old_size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
143+
assert!(old_size < new_size);
144+
145+
ascend[2*i+1] = reallocate(p1, new_size, ALIGN, old_size);
146+
sanity_check(ascend.as_slice());
147+
148+
ascend[2*i] = reallocate(p0, new_size, ALIGN, old_size);
149+
sanity_check(ascend.as_slice());
150+
}
151+
}
152+
153+
// Test 4: turn the square back into a triangle, bottom to top.
154+
unsafe fn test_4(ascend: &mut [*mut u8]) {
155+
let old_size = idx_to_size(COUNT-1);
156+
for i in range(0u, COUNT / 2).rev() {
157+
let (p0, p1, new_size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
158+
assert!(new_size < old_size);
159+
160+
ascend[2*i+1] = reallocate(p1, new_size, ALIGN, old_size);
161+
sanity_check(ascend.as_slice());
162+
163+
ascend[2*i] = reallocate(p0, new_size, ALIGN, old_size);
164+
sanity_check(ascend.as_slice());
165+
}
166+
}
167+
}

0 commit comments

Comments
 (0)