Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
ec897f91
R
Rust
项目概览
int
/
Rust
接近 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
ec897f91
编写于
7月 22, 2016
作者:
O
Oliver Schneider
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
don't allow runtime-aligning of memory
上级
613d15c6
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
79 addition
and
87 deletion
+79
-87
src/interpreter/mod.rs
src/interpreter/mod.rs
+4
-8
src/interpreter/terminator.rs
src/interpreter/terminator.rs
+1
-3
src/memory.rs
src/memory.rs
+70
-72
tests/compile-fail/oom.rs
tests/compile-fail/oom.rs
+1
-1
tests/compile-fail/oom2.rs
tests/compile-fail/oom2.rs
+1
-1
tests/compile-fail/out_of_bounds_read.rs
tests/compile-fail/out_of_bounds_read.rs
+1
-1
tests/compile-fail/out_of_bounds_read2.rs
tests/compile-fail/out_of_bounds_read2.rs
+1
-1
未找到文件。
src/interpreter/mod.rs
浏览文件 @
ec897f91
...
...
@@ -535,11 +535,9 @@ fn eval_assignment(&mut self, lvalue: &mir::Lvalue<'tcx>, rvalue: &mir::Rvalue<'
};
let
src
=
self
.eval_operand
(
operand
)
?
;
src
.check_align
(
elem_align
)
?
;
dest
.check_align
(
elem_align
)
?
;
for
i
in
0
..
length
{
let
elem_dest
=
dest
.offset
((
i
*
elem_size
)
as
isize
);
self
.memory
.copy
(
src
,
elem_dest
,
elem_size
)
?
;
self
.memory
.copy
(
src
,
elem_dest
,
elem_size
,
elem_align
)
?
;
}
}
...
...
@@ -603,17 +601,17 @@ fn eval_assignment(&mut self, lvalue: &mir::Lvalue<'tcx>, rvalue: &mir::Rvalue<'
let
src
=
self
.eval_operand
(
operand
)
?
;
let
src_ty
=
self
.operand_ty
(
operand
);
// FIXME(solson): Wrong for almost everything.
// FIXME: check alignment
warn!
(
"misc cast from {:?} to {:?}"
,
src_ty
,
dest_ty
);
let
dest_size
=
self
.type_size
(
dest_ty
);
let
src_size
=
self
.type_size
(
src_ty
);
let
dest_align
=
self
.type_align
(
dest_ty
);
// Hack to support fat pointer -> thin pointer casts to keep tests for
// other things passing for now.
let
is_fat_ptr_cast
=
pointee_type
(
src_ty
)
.map_or
(
false
,
|
ty
|
!
self
.type_is_sized
(
ty
));
if
dest_size
==
src_size
||
is_fat_ptr_cast
{
self
.memory
.copy
(
src
,
dest
,
dest_size
)
?
;
self
.memory
.copy
(
src
,
dest
,
dest_size
,
dest_align
)
?
;
}
else
{
return
Err
(
EvalError
::
Unimplemented
(
format!
(
"can't handle cast: {:?}"
,
rvalue
)));
}
...
...
@@ -858,9 +856,7 @@ fn operand_ty(&self, operand: &mir::Operand<'tcx>) -> Ty<'tcx> {
fn
move_
(
&
mut
self
,
src
:
Pointer
,
dest
:
Pointer
,
ty
:
Ty
<
'tcx
>
)
->
EvalResult
<
'tcx
,
()
>
{
let
size
=
self
.type_size
(
ty
);
let
align
=
self
.type_align
(
ty
);
src
.check_align
(
align
)
?
;
dest
.check_align
(
align
)
?
;
self
.memory
.copy
(
src
,
dest
,
size
)
?
;
self
.memory
.copy
(
src
,
dest
,
size
,
align
)
?
;
Ok
(())
}
...
...
src/interpreter/terminator.rs
浏览文件 @
ec897f91
...
...
@@ -291,11 +291,9 @@ fn call_intrinsic(
let
elem_size
=
self
.type_size
(
elem_ty
);
let
elem_align
=
self
.type_align
(
elem_ty
);
let
src
=
self
.memory
.read_ptr
(
args_ptrs
[
0
])
?
;
src
.check_align
(
elem_align
)
?
;
let
dest
=
self
.memory
.read_ptr
(
args_ptrs
[
1
])
?
;
dest
.check_align
(
elem_align
)
?
;
let
count
=
self
.memory
.read_isize
(
args_ptrs
[
2
])
?
;
self
.memory
.copy
(
src
,
dest
,
count
as
usize
*
elem_size
)
?
;
self
.memory
.copy
(
src
,
dest
,
count
as
usize
*
elem_size
,
elem_align
)
?
;
}
"discriminant_value"
=>
{
...
...
src/memory.rs
浏览文件 @
ec897f91
...
...
@@ -51,25 +51,6 @@ fn zst_ptr() -> Self {
offset
:
0
,
}
}
pub
fn
is_aligned_to
(
&
self
,
align
:
usize
)
->
bool
{
self
.offset
%
align
==
0
}
pub
fn
check_align
(
&
self
,
align
:
usize
)
->
EvalResult
<
'static
,
()
>
{
if
self
.is_aligned_to
(
align
)
{
Ok
(())
}
else
{
let
mut
best
=
self
.offset
;
let
mut
i
=
1
;
while
best
>
0
&&
(
best
&
1
==
0
)
{
best
>>=
1
;
i
<<=
1
;
}
Err
(
EvalError
::
AlignmentCheckFailed
{
required
:
align
,
has
:
i
,
})
}
}
}
#[derive(Debug,
Copy,
Clone,
Hash,
Eq,
PartialEq)]
...
...
@@ -118,11 +99,11 @@ pub fn new(layout: &'a TargetDataLayout, max_memory: usize) -> Self {
bytes
:
Vec
::
new
(),
relocations
:
BTreeMap
::
new
(),
undef_mask
:
UndefMask
::
new
(
0
),
align
:
0
,
align
:
1
,
};
mem
.alloc_map
.insert
(
ZST_ALLOC_ID
,
alloc
);
// check that additional zst allocs work
debug_assert!
(
mem
.allocate
(
0
,
0
)
.unwrap
()
.points_to_zst
());
debug_assert!
(
mem
.allocate
(
0
,
1
)
.unwrap
()
.points_to_zst
());
debug_assert!
(
mem
.get
(
ZST_ALLOC_ID
)
.is_ok
());
mem
}
...
...
@@ -155,24 +136,22 @@ pub fn create_fn_ptr(&mut self, def_id: DefId, substs: &'tcx Substs<'tcx>, fn_ty
}
pub
fn
allocate
(
&
mut
self
,
size
:
usize
,
align
:
usize
)
->
EvalResult
<
'tcx
,
Pointer
>
{
assert
!
(
align
!=
0
);
if
size
==
0
{
return
Ok
(
Pointer
::
zst_ptr
());
}
// make sure we can offset the result pointer by the worst possible alignment
// this allows cheaply checking for alignment directly in the pointer
let
least_aligned_size
=
size
+
align
;
if
self
.memory_size
-
self
.memory_usage
<
size
{
return
Err
(
EvalError
::
OutOfMemory
{
allocation_size
:
least_aligned_
size
,
allocation_size
:
size
,
memory_size
:
self
.memory_size
,
memory_usage
:
self
.memory_usage
,
});
}
self
.memory_usage
+=
size
;
let
alloc
=
Allocation
{
bytes
:
vec!
[
0
;
least_aligned_
size
],
bytes
:
vec!
[
0
;
size
],
relocations
:
BTreeMap
::
new
(),
undef_mask
:
UndefMask
::
new
(
least_aligned_
size
),
undef_mask
:
UndefMask
::
new
(
size
),
align
:
align
,
};
let
id
=
self
.next_id
;
...
...
@@ -180,15 +159,15 @@ pub fn allocate(&mut self, size: usize, align: usize) -> EvalResult<'tcx, Pointe
self
.alloc_map
.insert
(
id
,
alloc
);
Ok
(
Pointer
{
alloc_id
:
id
,
// offset by the alignment, so larger accesses will fail
offset
:
align
,
offset
:
0
,
})
}
// TODO(solson): Track which allocations were returned from __rust_allocate and report an error
// when reallocating/deallocating any others.
pub
fn
reallocate
(
&
mut
self
,
ptr
:
Pointer
,
new_size
:
usize
,
align
:
usize
)
->
EvalResult
<
'tcx
,
Pointer
>
{
if
ptr
.offset
!=
self
.get
(
ptr
.alloc_id
)
?
.align
{
// TODO(solson): Report error about non-__rust_allocate'd pointer.
if
ptr
.offset
!=
0
{
// TODO(solson): Report error about non-__rust_allocate'd pointer.
return
Err
(
EvalError
::
Unimplemented
(
format!
(
"bad pointer offset: {}"
,
ptr
.offset
)));
}
...
...
@@ -197,27 +176,26 @@ pub fn reallocate(&mut self, ptr: Pointer, new_size: usize, align: usize) -> Eva
}
let
size
=
self
.get
(
ptr
.alloc_id
)
?
.bytes
.len
();
let
least_aligned_size
=
new_size
+
align
;
if
least_aligned
_size
>
size
{
let
amount
=
least_aligned
_size
-
size
;
if
new
_size
>
size
{
let
amount
=
new
_size
-
size
;
self
.memory_usage
+=
amount
;
let
alloc
=
self
.get_mut
(
ptr
.alloc_id
)
?
;
alloc
.bytes
.extend
(
iter
::
repeat
(
0
)
.take
(
amount
));
alloc
.undef_mask
.grow
(
amount
,
false
);
}
else
if
size
>
least_aligned
_size
{
}
else
if
size
>
new
_size
{
// it's possible to cause miri to use arbitrary amounts of memory that aren't detectable
// through the memory_usage value, by allocating a lot and reallocating to zero
self
.memory_usage
-=
size
-
least_aligned
_size
;
self
.clear_relocations
(
ptr
.offset
(
least_aligned_size
as
isize
),
size
-
least_aligned
_size
)
?
;
self
.memory_usage
-=
size
-
new
_size
;
self
.clear_relocations
(
ptr
.offset
(
new_size
as
isize
),
size
-
new
_size
)
?
;
let
alloc
=
self
.get_mut
(
ptr
.alloc_id
)
?
;
alloc
.bytes
.truncate
(
least_aligned
_size
);
alloc
.undef_mask
.truncate
(
least_aligned
_size
);
alloc
.bytes
.truncate
(
new
_size
);
alloc
.undef_mask
.truncate
(
new
_size
);
}
Ok
(
Pointer
{
alloc_id
:
ptr
.alloc_id
,
offset
:
align
,
offset
:
0
,
})
}
...
...
@@ -226,7 +204,7 @@ pub fn deallocate(&mut self, ptr: Pointer) -> EvalResult<'tcx, ()> {
if
ptr
.points_to_zst
()
{
return
Ok
(());
}
if
ptr
.offset
!=
self
.get
(
ptr
.alloc_id
)
?
.align
{
if
ptr
.offset
!=
0
{
// TODO(solson): Report error about non-__rust_allocate'd pointer.
return
Err
(
EvalError
::
Unimplemented
(
format!
(
"bad pointer offset: {}"
,
ptr
.offset
)));
}
...
...
@@ -251,6 +229,24 @@ pub fn pointer_size(&self) -> usize {
pub
fn
endianess
(
&
self
)
->
layout
::
Endian
{
self
.layout.endian
}
pub
fn
check_align
(
&
self
,
ptr
:
Pointer
,
align
:
usize
)
->
EvalResult
<
'tcx
,
()
>
{
let
alloc
=
self
.get
(
ptr
.alloc_id
)
?
;
if
alloc
.align
<
align
{
return
Err
(
EvalError
::
AlignmentCheckFailed
{
has
:
alloc
.align
,
required
:
align
,
});
}
if
ptr
.offset
%
align
==
0
{
Ok
(())
}
else
{
Err
(
EvalError
::
AlignmentCheckFailed
{
has
:
ptr
.offset
%
align
,
required
:
align
,
})
}
}
}
/// Allocation accessors
...
...
@@ -368,7 +364,8 @@ fn get_bytes_unchecked_mut(&mut self, ptr: Pointer, size: usize) -> EvalResult<'
Ok
(
&
mut
alloc
.bytes
[
ptr
.offset
..
ptr
.offset
+
size
])
}
fn
get_bytes
(
&
self
,
ptr
:
Pointer
,
size
:
usize
)
->
EvalResult
<
'tcx
,
&
[
u8
]
>
{
fn
get_bytes
(
&
self
,
ptr
:
Pointer
,
size
:
usize
,
align
:
usize
)
->
EvalResult
<
'tcx
,
&
[
u8
]
>
{
self
.check_align
(
ptr
,
align
)
?
;
if
self
.relocations
(
ptr
,
size
)
?
.count
()
!=
0
{
return
Err
(
EvalError
::
ReadPointerAsBytes
);
}
...
...
@@ -376,7 +373,8 @@ fn get_bytes(&self, ptr: Pointer, size: usize) -> EvalResult<'tcx, &[u8]> {
self
.get_bytes_unchecked
(
ptr
,
size
)
}
fn
get_bytes_mut
(
&
mut
self
,
ptr
:
Pointer
,
size
:
usize
)
->
EvalResult
<
'tcx
,
&
mut
[
u8
]
>
{
fn
get_bytes_mut
(
&
mut
self
,
ptr
:
Pointer
,
size
:
usize
,
align
:
usize
)
->
EvalResult
<
'tcx
,
&
mut
[
u8
]
>
{
self
.check_align
(
ptr
,
align
)
?
;
self
.clear_relocations
(
ptr
,
size
)
?
;
self
.mark_definedness
(
ptr
,
size
,
true
)
?
;
self
.get_bytes_unchecked_mut
(
ptr
,
size
)
...
...
@@ -385,11 +383,11 @@ fn get_bytes_mut(&mut self, ptr: Pointer, size: usize) -> EvalResult<'tcx, &mut
/// Reading and writing
impl
<
'a
,
'tcx
>
Memory
<
'a
,
'tcx
>
{
pub
fn
copy
(
&
mut
self
,
src
:
Pointer
,
dest
:
Pointer
,
size
:
usize
)
->
EvalResult
<
'tcx
,
()
>
{
pub
fn
copy
(
&
mut
self
,
src
:
Pointer
,
dest
:
Pointer
,
size
:
usize
,
align
:
usize
)
->
EvalResult
<
'tcx
,
()
>
{
self
.check_relocation_edges
(
src
,
size
)
?
;
let
src_bytes
=
self
.get_bytes_unchecked_mut
(
src
,
size
)
?
.as_mut_ptr
();
let
dest_bytes
=
self
.get_bytes_mut
(
dest
,
size
)
?
.as_mut_ptr
();
let
dest_bytes
=
self
.get_bytes_mut
(
dest
,
size
,
align
)
?
.as_mut_ptr
();
// SAFE: The above indexing would have panicked if there weren't at least `size` bytes
// behind `src` and `dest`. Also, we use the overlapping-safe `ptr::copy` if `src` and
...
...
@@ -409,17 +407,17 @@ pub fn copy(&mut self, src: Pointer, dest: Pointer, size: usize) -> EvalResult<'
}
pub
fn
read_bytes
(
&
self
,
ptr
:
Pointer
,
size
:
usize
)
->
EvalResult
<
'tcx
,
&
[
u8
]
>
{
self
.get_bytes
(
ptr
,
size
)
self
.get_bytes
(
ptr
,
size
,
1
)
}
pub
fn
write_bytes
(
&
mut
self
,
ptr
:
Pointer
,
src
:
&
[
u8
])
->
EvalResult
<
'tcx
,
()
>
{
let
bytes
=
self
.get_bytes_mut
(
ptr
,
src
.len
())
?
;
let
bytes
=
self
.get_bytes_mut
(
ptr
,
src
.len
()
,
1
)
?
;
bytes
.clone_from_slice
(
src
);
Ok
(())
}
pub
fn
write_repeat
(
&
mut
self
,
ptr
:
Pointer
,
val
:
u8
,
count
:
usize
)
->
EvalResult
<
'tcx
,
()
>
{
let
bytes
=
self
.get_bytes_mut
(
ptr
,
count
)
?
;
let
bytes
=
self
.get_bytes_mut
(
ptr
,
count
,
1
)
?
;
for
b
in
bytes
{
*
b
=
val
;
}
Ok
(())
}
...
...
@@ -465,8 +463,7 @@ pub fn write_primval(&mut self, ptr: Pointer, val: PrimVal) -> EvalResult<'tcx,
}
pub
fn
read_bool
(
&
self
,
ptr
:
Pointer
)
->
EvalResult
<
'tcx
,
bool
>
{
ptr
.check_align
(
self
.layout.i1_align
.abi
()
as
usize
)
?
;
let
bytes
=
self
.get_bytes
(
ptr
,
1
)
?
;
let
bytes
=
self
.get_bytes
(
ptr
,
1
,
self
.layout.i1_align
.abi
()
as
usize
)
?
;
match
bytes
[
0
]
{
0
=>
Ok
(
false
),
1
=>
Ok
(
true
),
...
...
@@ -475,42 +472,43 @@ pub fn read_bool(&self, ptr: Pointer) -> EvalResult<'tcx, bool> {
}
pub
fn
write_bool
(
&
mut
self
,
ptr
:
Pointer
,
b
:
bool
)
->
EvalResult
<
'tcx
,
()
>
{
ptr
.check_align
(
self
.layout.i1_align
.abi
()
as
usize
)
?
;
self
.get_bytes_mut
(
ptr
,
1
)
.map
(|
bytes
|
bytes
[
0
]
=
b
as
u8
)
let
align
=
self
.layout.i1_align
.abi
()
as
usize
;
self
.get_bytes_mut
(
ptr
,
1
,
align
)
.map
(|
bytes
|
bytes
[
0
]
=
b
as
u8
)
}
fn
check_int_align
(
&
self
,
ptr
:
Pointer
,
size
:
usize
)
->
EvalResult
<
'tcx
,
()
>
{
fn
int_align
(
&
self
,
size
:
usize
)
->
EvalResult
<
'tcx
,
usize
>
{
match
size
{
1
=>
ptr
.check_align
(
self
.layout.i8_align
.abi
()
as
usize
),
2
=>
ptr
.check_align
(
self
.layout.i16_align
.abi
()
as
usize
),
4
=>
ptr
.check_align
(
self
.layout.i32_align
.abi
()
as
usize
),
8
=>
ptr
.check_align
(
self
.layout.i64_align
.abi
()
as
usize
),
1
=>
Ok
(
self
.layout.i8_align
.abi
()
as
usize
),
2
=>
Ok
(
self
.layout.i16_align
.abi
()
as
usize
),
4
=>
Ok
(
self
.layout.i32_align
.abi
()
as
usize
),
8
=>
Ok
(
self
.layout.i64_align
.abi
()
as
usize
),
_
=>
panic!
(
"bad integer size"
),
}
}
pub
fn
read_int
(
&
self
,
ptr
:
Pointer
,
size
:
usize
)
->
EvalResult
<
'tcx
,
i64
>
{
self
.check_int_align
(
ptr
,
size
)
?
;
self
.get_bytes
(
ptr
,
size
)
.map
(|
b
|
read_target_int
(
self
.endianess
(),
b
)
.unwrap
())
let
align
=
self
.int_align
(
size
)
?
;
self
.get_bytes
(
ptr
,
size
,
align
)
.map
(|
b
|
read_target_int
(
self
.endianess
(),
b
)
.unwrap
())
}
pub
fn
write_int
(
&
mut
self
,
ptr
:
Pointer
,
n
:
i64
,
size
:
usize
)
->
EvalResult
<
'tcx
,
()
>
{
self
.check_int_align
(
ptr
,
size
)
?
;
let
align
=
self
.int_align
(
size
)
?
;
let
endianess
=
self
.endianess
();
let
b
=
self
.get_bytes_mut
(
ptr
,
size
)
?
;
let
b
=
self
.get_bytes_mut
(
ptr
,
size
,
align
)
?
;
write_target_int
(
endianess
,
b
,
n
)
.unwrap
();
Ok
(())
}
pub
fn
read_uint
(
&
self
,
ptr
:
Pointer
,
size
:
usize
)
->
EvalResult
<
'tcx
,
u64
>
{
self
.check_int_align
(
ptr
,
size
)
?
;
self
.get_bytes
(
ptr
,
size
)
.map
(|
b
|
read_target_uint
(
self
.endianess
(),
b
)
.unwrap
())
let
align
=
self
.int_align
(
size
)
?
;
self
.get_bytes
(
ptr
,
size
,
align
)
.map
(|
b
|
read_target_uint
(
self
.endianess
(),
b
)
.unwrap
())
}
pub
fn
write_uint
(
&
mut
self
,
ptr
:
Pointer
,
n
:
u64
,
size
:
usize
)
->
EvalResult
<
'tcx
,
()
>
{
self
.check_int_align
(
ptr
,
size
)
?
;
let
align
=
self
.int_align
(
size
)
?
;
let
endianess
=
self
.endianess
();
let
b
=
self
.get_bytes_mut
(
ptr
,
size
)
?
;
let
b
=
self
.get_bytes_mut
(
ptr
,
size
,
align
)
?
;
write_target_uint
(
endianess
,
b
,
n
)
.unwrap
();
Ok
(())
}
...
...
@@ -534,29 +532,29 @@ pub fn write_usize(&mut self, ptr: Pointer, n: u64) -> EvalResult<'tcx, ()> {
}
pub
fn
write_f32
(
&
mut
self
,
ptr
:
Pointer
,
f
:
f32
)
->
EvalResult
<
'tcx
,
()
>
{
ptr
.check_align
(
self
.layout.f32_align
.abi
()
as
usize
)
?
;
let
endianess
=
self
.endianess
();
let
b
=
self
.get_bytes_mut
(
ptr
,
4
)
?
;
let
align
=
self
.layout.f32_align
.abi
()
as
usize
;
let
b
=
self
.get_bytes_mut
(
ptr
,
4
,
align
)
?
;
write_target_f32
(
endianess
,
b
,
f
)
.unwrap
();
Ok
(())
}
pub
fn
write_f64
(
&
mut
self
,
ptr
:
Pointer
,
f
:
f64
)
->
EvalResult
<
'tcx
,
()
>
{
ptr
.check_align
(
self
.layout.f64_align
.abi
()
as
usize
)
?
;
let
endianess
=
self
.endianess
();
let
b
=
self
.get_bytes_mut
(
ptr
,
8
)
?
;
let
align
=
self
.layout.f64_align
.abi
()
as
usize
;
let
b
=
self
.get_bytes_mut
(
ptr
,
8
,
align
)
?
;
write_target_f64
(
endianess
,
b
,
f
)
.unwrap
();
Ok
(())
}
pub
fn
read_f32
(
&
self
,
ptr
:
Pointer
)
->
EvalResult
<
'tcx
,
f32
>
{
ptr
.check_align
(
self
.layout.f32_align
.abi
()
as
usize
)
?
;
self
.get_bytes
(
ptr
,
4
)
.map
(|
b
|
read_target_f32
(
self
.endianess
(),
b
)
.unwrap
())
self
.get_bytes
(
ptr
,
4
,
self
.layout.f32_align
.abi
()
as
usize
)
.map
(|
b
|
read_target_f32
(
self
.endianess
(),
b
)
.unwrap
())
}
pub
fn
read_f64
(
&
self
,
ptr
:
Pointer
)
->
EvalResult
<
'tcx
,
f64
>
{
ptr
.check_align
(
self
.layout.f64_align
.abi
()
as
usize
)
?
;
self
.get_bytes
(
ptr
,
8
)
.map
(|
b
|
read_target_f64
(
self
.endianess
(),
b
)
.unwrap
())
self
.get_bytes
(
ptr
,
8
,
self
.layout.f64_align
.abi
()
as
usize
)
.map
(|
b
|
read_target_f64
(
self
.endianess
(),
b
)
.unwrap
())
}
}
...
...
tests/compile-fail/oom.rs
浏览文件 @
ec897f91
...
...
@@ -6,6 +6,6 @@ fn bar() {
assert_eq!
(
x
,
6
);
}
fn
main
()
{
//~ ERROR tried to allocate
8
more bytes, but only 0 bytes are free of the 0 byte memory
fn
main
()
{
//~ ERROR tried to allocate
4
more bytes, but only 0 bytes are free of the 0 byte memory
bar
();
}
tests/compile-fail/oom2.rs
浏览文件 @
ec897f91
...
...
@@ -3,7 +3,7 @@
fn
bar
(
i
:
i32
)
{
if
i
<
1000
{
bar
(
i
+
1
)
//~ ERROR tried to allocate
8
more bytes, but only 1 bytes are free of the 1000 byte memory
bar
(
i
+
1
)
//~ ERROR tried to allocate
4
more bytes, but only 1 bytes are free of the 1000 byte memory
//~^NOTE inside call to bar
//~|NOTE inside call to bar
//~|NOTE inside call to bar
...
...
tests/compile-fail/out_of_bounds_read.rs
浏览文件 @
ec897f91
fn
main
()
{
let
v
:
Vec
<
u8
>
=
vec!
[
1
,
2
];
let
x
=
unsafe
{
*
v
.get_unchecked
(
5
)
};
//~ ERROR: which has size
3
let
x
=
unsafe
{
*
v
.get_unchecked
(
5
)
};
//~ ERROR: which has size
2
panic!
(
"this should never print: {}"
,
x
);
}
tests/compile-fail/out_of_bounds_read2.rs
浏览文件 @
ec897f91
fn
main
()
{
let
v
:
Vec
<
u8
>
=
vec!
[
1
,
2
];
let
x
=
unsafe
{
*
v
.get_unchecked
(
5
)
};
//~ ERROR: memory access of
6..7
outside bounds of allocation
let
x
=
unsafe
{
*
v
.get_unchecked
(
5
)
};
//~ ERROR: memory access of
5..6
outside bounds of allocation
panic!
(
"this should never print: {}"
,
x
);
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录