When a vec/str bounds check fails, include the bad index and the length of the str/vec in the fail message.
This commit is contained in:
parent
2f95f7d8de
commit
1c76d189c0
@ -40,6 +40,16 @@ fn rt_fail_(expr: *c_char, file: *c_char, line: size_t) {
|
||||
rustrt::rust_upcall_fail(expr, file, line);
|
||||
}
|
||||
|
||||
#[rt(fail_bounds_check)]
|
||||
fn rt_fail_bounds_check(file: *c_char, line: size_t,
|
||||
index: size_t, len: size_t) {
|
||||
let msg = fmt!("index out of bounds: the len is %d but the index is %d",
|
||||
len as int, index as int);
|
||||
do str::as_buf(msg) |p, _len| {
|
||||
rt_fail_(p as *c_char, file, line);
|
||||
}
|
||||
}
|
||||
|
||||
#[rt(exchange_malloc)]
|
||||
fn rt_exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
|
||||
return rustrt::rust_upcall_exchange_malloc(td, size);
|
||||
|
@ -344,3 +344,21 @@ fn trans_fail_value(bcx: block, sp_opt: Option<span>, V_fail_str: ValueRef)
|
||||
Unreachable(bcx);
|
||||
return bcx;
|
||||
}
|
||||
|
||||
fn trans_fail_bounds_check(bcx: block, sp: span,
|
||||
index: ValueRef, len: ValueRef) -> block {
|
||||
let _icx = bcx.insn_ctxt("trans_fail_bounds_check");
|
||||
let ccx = bcx.ccx();
|
||||
|
||||
let loc = codemap::lookup_char_pos(bcx.sess().parse_sess.cm, sp.lo);
|
||||
let line = C_int(ccx, loc.line as int);
|
||||
let filename_cstr = C_cstr(bcx.ccx(), loc.file.name);
|
||||
let filename = PointerCast(bcx, filename_cstr, T_ptr(T_i8()));
|
||||
|
||||
let args = ~[filename, line, index, len];
|
||||
let bcx = callee::trans_rtcall(bcx, ~"fail_bounds_check", args,
|
||||
expr::Ignore);
|
||||
Unreachable(bcx);
|
||||
return bcx;
|
||||
}
|
||||
|
||||
|
@ -946,7 +946,9 @@ fn trans_index(bcx: block,
|
||||
|
||||
let bounds_check = ICmp(bcx, lib::llvm::IntUGE, scaled_ix, len);
|
||||
let bcx = do with_cond(bcx, bounds_check) |bcx| {
|
||||
controlflow::trans_fail(bcx, Some(index_expr.span), ~"bounds check")
|
||||
let unscaled_len = UDiv(bcx, len, vt.llunit_size);
|
||||
controlflow::trans_fail_bounds_check(bcx, index_expr.span,
|
||||
ix_val, unscaled_len)
|
||||
};
|
||||
let elt = InBoundsGEP(bcx, base, ~[ix_val]);
|
||||
let elt = PointerCast(bcx, elt, T_ptr(vt.llunit_ty));
|
||||
|
@ -1,5 +1,5 @@
|
||||
// xfail-test
|
||||
// error-pattern:bounds check
|
||||
// error-pattern:index out of bounds
|
||||
|
||||
fn main() {
|
||||
let x = ~[1u,2u,3u];
|
||||
@ -14,4 +14,4 @@ fn main() {
|
||||
|
||||
// This should fail.
|
||||
error!("ov2 0x%x", x[idx]);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// xfail-test
|
||||
// error-pattern:bounds check
|
||||
// error-pattern:index out of bounds
|
||||
|
||||
#[cfg(target_arch="x86")]
|
||||
fn main() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
// error-pattern:bounds check
|
||||
// error-pattern:index out of bounds
|
||||
|
||||
fn main() {
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// error-pattern:bounds check
|
||||
// error-pattern:index out of bounds: the len is 1024 but the index is -1
|
||||
fn main() {
|
||||
let v = vec::from_fn(1024u, {|n| n});
|
||||
// this should trip a bounds check
|
||||
|
@ -1,6 +1,6 @@
|
||||
// -*- rust -*-
|
||||
|
||||
// error-pattern:bounds check
|
||||
// error-pattern:index out of bounds: the len is 5 but the index is 5
|
||||
fn main() {
|
||||
let s: ~str = ~"hello";
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// -*- rust -*-
|
||||
|
||||
// error-pattern:bounds check
|
||||
// error-pattern:index out of bounds: the len is 1 but the index is 2
|
||||
fn main() {
|
||||
let v: ~[int] = ~[10];
|
||||
let x: int = 0;
|
||||
|
@ -1,6 +1,6 @@
|
||||
// -*- rust -*-
|
||||
|
||||
// error-pattern:bounds check
|
||||
// error-pattern:index out of bounds: the len is 2 but the index is -1
|
||||
fn main() {
|
||||
let v: ~[int] = ~[10, 20];
|
||||
let x: int = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user