Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
986b3a07
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,发现更多精彩内容 >>
未验证
提交
986b3a07
编写于
11月 17, 2016
作者:
O
Oliver Schneider
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
layout computation can fail, make it fail with a miri error
上级
26ccc1e4
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
71 addition
and
60 deletion
+71
-60
src/error.rs
src/error.rs
+7
-2
src/interpreter/mod.rs
src/interpreter/mod.rs
+31
-31
src/interpreter/terminator/intrinsics.rs
src/interpreter/terminator/intrinsics.rs
+11
-11
src/interpreter/terminator/mod.rs
src/interpreter/terminator/mod.rs
+13
-12
src/interpreter/vtable.rs
src/interpreter/vtable.rs
+2
-2
src/memory.rs
src/memory.rs
+2
-2
tests/compile-fail/repeat.rs
tests/compile-fail/repeat.rs
+5
-0
未找到文件。
src/error.rs
浏览文件 @
986b3a07
use
std
::
error
::
Error
;
use
std
::
fmt
;
use
rustc
::
mir
;
use
rustc
::
ty
::{
BareFnTy
,
Ty
,
FnSig
};
use
rustc
::
ty
::{
BareFnTy
,
Ty
,
FnSig
,
layout
};
use
syntax
::
abi
::
Abi
;
use
memory
::
Pointer
;
use
rustc_const_math
::
ConstMathErr
;
use
syntax
::
codemap
::
Span
;
#[derive(Clone,
Debug
,
PartialEq,
Eq
)]
#[derive(Clone,
Debug)]
pub
enum
EvalError
<
'tcx
>
{
FunctionPointerTyMismatch
(
Abi
,
&
'tcx
FnSig
<
'tcx
>
,
&
'tcx
BareFnTy
<
'tcx
>
),
NoMirFor
(
String
),
...
...
@@ -50,6 +50,7 @@ pub enum EvalError<'tcx> {
TypeNotPrimitive
(
Ty
<
'tcx
>
),
ReallocatedFrozenMemory
,
DeallocatedFrozenMemory
,
Layout
(
layout
::
LayoutError
<
'tcx
>
),
}
pub
type
EvalResult
<
'tcx
,
T
>
=
Result
<
T
,
EvalError
<
'tcx
>>
;
...
...
@@ -116,6 +117,8 @@ fn description(&self) -> &str {
"tried to reallocate frozen memory"
,
EvalError
::
DeallocatedFrozenMemory
=>
"tried to deallocate frozen memory"
,
EvalError
::
Layout
(
_
)
=>
"rustc layout computation failed"
,
}
}
...
...
@@ -146,6 +149,8 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
has
,
required
),
EvalError
::
TypeNotPrimitive
(
ref
ty
)
=>
write!
(
f
,
"expected primitive type, got {}"
,
ty
),
EvalError
::
Layout
(
ref
err
)
=>
write!
(
f
,
"rustc layout computation failed: {:?}"
,
err
),
_
=>
write!
(
f
,
"{}"
,
self
.description
()),
}
}
...
...
src/interpreter/mod.rs
浏览文件 @
986b3a07
...
...
@@ -188,8 +188,8 @@ pub fn alloc_ptr_with_substs(
ty
:
Ty
<
'tcx
>
,
substs
:
&
'tcx
Substs
<
'tcx
>
)
->
EvalResult
<
'tcx
,
Pointer
>
{
let
size
=
self
.type_size_with_substs
(
ty
,
substs
)
.expect
(
"cannot alloc memory for unsized type"
);
let
align
=
self
.type_align_with_substs
(
ty
,
substs
);
let
size
=
self
.type_size_with_substs
(
ty
,
substs
)
?
.expect
(
"cannot alloc memory for unsized type"
);
let
align
=
self
.type_align_with_substs
(
ty
,
substs
)
?
;
self
.memory
.allocate
(
size
,
align
)
}
...
...
@@ -292,38 +292,38 @@ pub fn monomorphize(&self, ty: Ty<'tcx>, substs: &'tcx Substs<'tcx>) -> Ty<'tcx>
self
.tcx
.normalize_associated_type
(
&
substituted
)
}
fn
type_size
(
&
self
,
ty
:
Ty
<
'tcx
>
)
->
Option
<
usize
>
{
fn
type_size
(
&
self
,
ty
:
Ty
<
'tcx
>
)
->
EvalResult
<
'tcx
,
Option
<
usize
>
>
{
self
.type_size_with_substs
(
ty
,
self
.substs
())
}
fn
type_align
(
&
self
,
ty
:
Ty
<
'tcx
>
)
->
usize
{
fn
type_align
(
&
self
,
ty
:
Ty
<
'tcx
>
)
->
EvalResult
<
'tcx
,
usize
>
{
self
.type_align_with_substs
(
ty
,
self
.substs
())
}
fn
type_size_with_substs
(
&
self
,
ty
:
Ty
<
'tcx
>
,
substs
:
&
'tcx
Substs
<
'tcx
>
)
->
Option
<
usize
>
{
let
layout
=
self
.type_layout_with_substs
(
ty
,
substs
);
fn
type_size_with_substs
(
&
self
,
ty
:
Ty
<
'tcx
>
,
substs
:
&
'tcx
Substs
<
'tcx
>
)
->
EvalResult
<
'tcx
,
Option
<
usize
>
>
{
let
layout
=
self
.type_layout_with_substs
(
ty
,
substs
)
?
;
if
layout
.is_unsized
()
{
None
Ok
(
None
)
}
else
{
Some
(
layout
.size
(
&
self
.tcx.data_layout
)
.bytes
()
as
usize
)
Ok
(
Some
(
layout
.size
(
&
self
.tcx.data_layout
)
.bytes
()
as
usize
)
)
}
}
fn
type_align_with_substs
(
&
self
,
ty
:
Ty
<
'tcx
>
,
substs
:
&
'tcx
Substs
<
'tcx
>
)
->
usize
{
self
.type_layout_with_substs
(
ty
,
substs
)
.
align
(
&
self
.tcx.data_layout
)
.abi
()
as
usize
fn
type_align_with_substs
(
&
self
,
ty
:
Ty
<
'tcx
>
,
substs
:
&
'tcx
Substs
<
'tcx
>
)
->
EvalResult
<
'tcx
,
usize
>
{
self
.type_layout_with_substs
(
ty
,
substs
)
.
map
(|
layout
|
layout
.align
(
&
self
.tcx.data_layout
)
.abi
()
as
usize
)
}
fn
type_layout
(
&
self
,
ty
:
Ty
<
'tcx
>
)
->
&
'tcx
Layout
{
fn
type_layout
(
&
self
,
ty
:
Ty
<
'tcx
>
)
->
EvalResult
<
'tcx
,
&
'tcx
Layout
>
{
self
.type_layout_with_substs
(
ty
,
self
.substs
())
}
fn
type_layout_with_substs
(
&
self
,
ty
:
Ty
<
'tcx
>
,
substs
:
&
'tcx
Substs
<
'tcx
>
)
->
&
'tcx
Layout
{
fn
type_layout_with_substs
(
&
self
,
ty
:
Ty
<
'tcx
>
,
substs
:
&
'tcx
Substs
<
'tcx
>
)
->
EvalResult
<
'tcx
,
&
'tcx
Layout
>
{
// TODO(solson): Is this inefficient? Needs investigation.
let
ty
=
self
.monomorphize
(
ty
,
substs
);
self
.tcx
.infer_ctxt
(
None
,
None
,
Reveal
::
All
)
.enter
(|
infcx
|
{
// TODO(solson): Report this error properly.
ty
.layout
(
&
infcx
)
.
unwrap
(
)
ty
.layout
(
&
infcx
)
.
map_err
(
EvalError
::
Layout
)
})
}
...
...
@@ -482,7 +482,7 @@ fn eval_rvalue_into_lvalue(
)
->
EvalResult
<
'tcx
,
()
>
{
let
dest
=
self
.eval_lvalue
(
lvalue
)
?
;
let
dest_ty
=
self
.lvalue_ty
(
lvalue
);
let
dest_layout
=
self
.type_layout
(
dest_ty
);
let
dest_layout
=
self
.type_layout
(
dest_ty
)
?
;
use
rustc
::
mir
::
Rvalue
::
*
;
match
*
rvalue
{
...
...
@@ -516,7 +516,7 @@ fn eval_rvalue_into_lvalue(
Array
{
..
}
=>
{
let
elem_size
=
match
dest_ty
.sty
{
ty
::
TyArray
(
elem_ty
,
_
)
=>
self
.type_size
(
elem_ty
)
.expect
(
"array elements are sized"
)
as
u64
,
ty
::
TyArray
(
elem_ty
,
_
)
=>
self
.type_size
(
elem_ty
)
?
.expect
(
"array elements are sized"
)
as
u64
,
_
=>
bug!
(
"tried to assign {:?} to non-array type {:?}"
,
kind
,
dest_ty
),
};
let
offsets
=
(
0
..
)
.map
(|
i
|
i
*
elem_size
);
...
...
@@ -556,9 +556,9 @@ fn eval_rvalue_into_lvalue(
if
let
Some
(
operand
)
=
operands
.get
(
0
)
{
assert_eq!
(
operands
.len
(),
1
);
let
operand_ty
=
self
.operand_ty
(
operand
);
assert_eq!
(
self
.type_size
(
operand_ty
),
Some
(
0
));
assert_eq!
(
self
.type_size
(
operand_ty
)
?
,
Some
(
0
));
}
let
value_size
=
self
.type_size
(
dest_ty
)
.expect
(
"pointer types are sized"
);
let
value_size
=
self
.type_size
(
dest_ty
)
?
.expect
(
"pointer types are sized"
);
let
zero
=
PrimVal
::
from_int_with_size
(
0
,
value_size
);
self
.write_primval
(
dest
,
zero
)
?
;
}
...
...
@@ -575,7 +575,7 @@ fn eval_rvalue_into_lvalue(
}
else
{
for
operand
in
operands
{
let
operand_ty
=
self
.operand_ty
(
operand
);
assert_eq!
(
self
.type_size
(
operand_ty
),
Some
(
0
));
assert_eq!
(
self
.type_size
(
operand_ty
)
?
,
Some
(
0
));
}
let
(
offset
,
ty
)
=
self
.nonnull_offset_and_ty
(
dest_ty
,
nndiscr
,
discrfield
)
?
;
...
...
@@ -583,7 +583,7 @@ fn eval_rvalue_into_lvalue(
let
dest
=
self
.force_allocation
(
dest
)
?
.to_ptr
();
let
dest
=
dest
.offset
(
offset
.bytes
()
as
isize
);
let
dest_size
=
self
.type_size
(
ty
)
.expect
(
"bad StructWrappedNullablePointer discrfield"
);
let
dest_size
=
self
.type_size
(
ty
)
?
.expect
(
"bad StructWrappedNullablePointer discrfield"
);
try!
(
self
.memory
.write_int
(
dest
,
0
,
dest_size
));
}
}
else
{
...
...
@@ -625,8 +625,8 @@ fn eval_rvalue_into_lvalue(
ty
::
TyArray
(
elem_ty
,
n
)
=>
(
elem_ty
,
n
),
_
=>
bug!
(
"tried to assign array-repeat to non-array type {:?}"
,
dest_ty
),
};
let
elem_size
=
self
.type_size
(
elem_ty
)
.expect
(
"repeat element type must be sized"
);
self
.inc_step_counter_and_check_limit
(
length
as
u64
)
?
;
let
elem_size
=
self
.type_size
(
elem_ty
)
?
.expect
(
"repeat element type must be sized"
);
let
value
=
self
.eval_operand
(
operand
)
?
;
// FIXME(solson)
...
...
@@ -797,7 +797,7 @@ fn get_field_ty(&self, ty: Ty<'tcx>, field_index: usize) -> EvalResult<'tcx, Ty<
}
fn
get_field_offset
(
&
self
,
ty
:
Ty
<
'tcx
>
,
field_index
:
usize
)
->
EvalResult
<
'tcx
,
Size
>
{
let
layout
=
self
.type_layout
(
ty
);
let
layout
=
self
.type_layout
(
ty
)
?
;
use
rustc
::
ty
::
layout
::
Layout
::
*
;
match
*
layout
{
...
...
@@ -816,7 +816,7 @@ fn get_field_offset(&self, ty: Ty<'tcx>, field_index: usize) -> EvalResult<'tcx,
}
fn
get_field_count
(
&
self
,
ty
:
Ty
<
'tcx
>
)
->
EvalResult
<
'tcx
,
usize
>
{
let
layout
=
self
.type_layout
(
ty
);
let
layout
=
self
.type_layout
(
ty
)
?
;
use
rustc
::
ty
::
layout
::
Layout
::
*
;
match
*
layout
{
...
...
@@ -944,7 +944,7 @@ fn eval_lvalue_projection(
)
->
EvalResult
<
'tcx
,
Lvalue
<
'tcx
>>
{
let
base
=
self
.eval_lvalue
(
&
proj
.base
)
?
;
let
base_ty
=
self
.lvalue_ty
(
&
proj
.base
);
let
base_layout
=
self
.type_layout
(
base_ty
);
let
base_layout
=
self
.type_layout
(
base_ty
)
?
;
use
rustc
::
mir
::
ProjectionElem
::
*
;
let
(
ptr
,
extra
)
=
match
proj
.elem
{
...
...
@@ -1043,7 +1043,7 @@ fn eval_lvalue_projection(
let
(
base_ptr
,
_
)
=
base
.to_ptr_and_extra
();
let
(
elem_ty
,
len
)
=
base
.elem_ty_and_len
(
base_ty
);
let
elem_size
=
self
.type_size
(
elem_ty
)
.expect
(
"slice element must be sized"
);
let
elem_size
=
self
.type_size
(
elem_ty
)
?
.expect
(
"slice element must be sized"
);
let
n_ptr
=
self
.eval_operand
(
operand
)
?
;
let
usize
=
self
.tcx.types.usize
;
let
n
=
self
.value_to_primval
(
n_ptr
,
usize
)
?
...
...
@@ -1059,7 +1059,7 @@ fn eval_lvalue_projection(
let
(
base_ptr
,
_
)
=
base
.to_ptr_and_extra
();
let
(
elem_ty
,
n
)
=
base
.elem_ty_and_len
(
base_ty
);
let
elem_size
=
self
.type_size
(
elem_ty
)
.expect
(
"sequence element must be sized"
);
let
elem_size
=
self
.type_size
(
elem_ty
)
?
.expect
(
"sequence element must be sized"
);
assert
!
(
n
>=
min_length
as
u64
);
let
index
=
if
from_end
{
...
...
@@ -1078,7 +1078,7 @@ fn eval_lvalue_projection(
let
(
base_ptr
,
_
)
=
base
.to_ptr_and_extra
();
let
(
elem_ty
,
n
)
=
base
.elem_ty_and_len
(
base_ty
);
let
elem_size
=
self
.type_size
(
elem_ty
)
.expect
(
"slice element must be sized"
);
let
elem_size
=
self
.type_size
(
elem_ty
)
?
.expect
(
"slice element must be sized"
);
assert
!
((
from
as
u64
)
<=
n
-
(
to
as
u64
));
let
ptr
=
base_ptr
.offset
(
from
as
isize
*
elem_size
as
isize
);
let
extra
=
LvalueExtra
::
Length
(
n
-
to
as
u64
-
from
as
u64
);
...
...
@@ -1098,8 +1098,8 @@ fn operand_ty(&self, operand: &mir::Operand<'tcx>) -> Ty<'tcx> {
}
fn
copy
(
&
mut
self
,
src
:
Pointer
,
dest
:
Pointer
,
ty
:
Ty
<
'tcx
>
)
->
EvalResult
<
'tcx
,
()
>
{
let
size
=
self
.type_size
(
ty
)
.expect
(
"cannot copy from an unsized type"
);
let
align
=
self
.type_align
(
ty
);
let
size
=
self
.type_size
(
ty
)
?
.expect
(
"cannot copy from an unsized type"
);
let
align
=
self
.type_align
(
ty
)
?
;
self
.memory
.copy
(
src
,
dest
,
size
,
align
)
?
;
Ok
(())
}
...
...
@@ -1368,7 +1368,7 @@ fn ty_to_primval_kind(&self, ty: Ty<'tcx>) -> EvalResult<'tcx, PrimValKind> {
ty
::
TyAdt
(
..
)
=>
{
use
rustc
::
ty
::
layout
::
Layout
::
*
;
if
let
CEnum
{
discr
,
signed
,
..
}
=
*
self
.type_layout
(
ty
)
{
if
let
CEnum
{
discr
,
signed
,
..
}
=
*
self
.type_layout
(
ty
)
?
{
let
size
=
discr
.size
()
.bytes
()
as
usize
;
if
signed
{
PrimValKind
::
from_int_size
(
size
)
...
...
@@ -1464,7 +1464,7 @@ fn read_value(&mut self, ptr: Pointer, ty: Ty<'tcx>) -> EvalResult<'tcx, Value>
ty
::
TyAdt
(
..
)
=>
{
use
rustc
::
ty
::
layout
::
Layout
::
*
;
if
let
CEnum
{
discr
,
signed
,
..
}
=
*
self
.type_layout
(
ty
)
{
if
let
CEnum
{
discr
,
signed
,
..
}
=
*
self
.type_layout
(
ty
)
?
{
let
size
=
discr
.size
()
.bytes
()
as
usize
;
if
signed
{
let
n
=
self
.memory
.read_int
(
ptr
,
size
)
?
;
...
...
@@ -1564,7 +1564,7 @@ fn unsize_into(
for
(
i
,
(
src_f
,
dst_f
))
in
iter
{
let
src_fty
=
monomorphize_field_ty
(
self
.tcx
,
src_f
,
substs_a
);
let
dst_fty
=
monomorphize_field_ty
(
self
.tcx
,
dst_f
,
substs_b
);
if
self
.type_size
(
dst_fty
)
==
Some
(
0
)
{
if
self
.type_size
(
dst_fty
)
?
==
Some
(
0
)
{
continue
;
}
let
src_field_offset
=
self
.get_field_offset
(
src_ty
,
i
)
?
.bytes
()
as
isize
;
...
...
src/interpreter/terminator/intrinsics.rs
浏览文件 @
986b3a07
...
...
@@ -144,8 +144,8 @@ pub(super) fn call_intrinsic(
"copy_nonoverlapping"
=>
{
// FIXME: check whether overlapping occurs
let
elem_ty
=
substs
.type_at
(
0
);
let
elem_size
=
self
.type_size
(
elem_ty
)
.expect
(
"cannot copy unsized value"
);
let
elem_align
=
self
.type_align
(
elem_ty
);
let
elem_size
=
self
.type_size
(
elem_ty
)
?
.expect
(
"cannot copy unsized value"
);
let
elem_align
=
self
.type_align
(
elem_ty
)
?
;
let
src
=
arg_vals
[
0
]
.read_ptr
(
&
self
.memory
)
?
;
let
dest
=
arg_vals
[
1
]
.read_ptr
(
&
self
.memory
)
?
;
let
count
=
self
.value_to_primval
(
arg_vals
[
2
],
usize
)
?
...
...
@@ -252,14 +252,14 @@ pub(super) fn call_intrinsic(
"min_align_of"
=>
{
let
elem_ty
=
substs
.type_at
(
0
);
let
elem_align
=
self
.type_align
(
elem_ty
);
let
elem_align
=
self
.type_align
(
elem_ty
)
?
;
let
align_val
=
self
.usize_primval
(
elem_align
as
u64
);
self
.write_primval
(
dest
,
align_val
)
?
;
}
"pref_align_of"
=>
{
let
ty
=
substs
.type_at
(
0
);
let
layout
=
self
.type_layout
(
ty
);
let
layout
=
self
.type_layout
(
ty
)
?
;
let
align
=
layout
.align
(
&
self
.tcx.data_layout
)
.pref
();
let
align_val
=
self
.usize_primval
(
align
);
self
.write_primval
(
dest
,
align_val
)
?
;
...
...
@@ -280,7 +280,7 @@ pub(super) fn call_intrinsic(
"offset"
=>
{
let
pointee_ty
=
substs
.type_at
(
0
);
let
pointee_size
=
self
.type_size
(
pointee_ty
)
.expect
(
"cannot offset a pointer to an unsized type"
)
as
isize
;
let
pointee_size
=
self
.type_size
(
pointee_ty
)
?
.expect
(
"cannot offset a pointer to an unsized type"
)
as
isize
;
let
offset
=
self
.value_to_primval
(
arg_vals
[
1
],
isize
)
?
.expect_int
(
"offset second arg not isize"
);
...
...
@@ -335,7 +335,7 @@ pub(super) fn call_intrinsic(
// `size_of_val` intrinsic, then change this back to
// .expect("size_of intrinsic called on unsized value")
// see https://github.com/rust-lang/rust/pull/37708
let
size
=
self
.type_size
(
ty
)
.unwrap_or
(
!
0
)
as
u64
;
let
size
=
self
.type_size
(
ty
)
?
.unwrap_or
(
!
0
)
as
u64
;
let
size_val
=
self
.usize_primval
(
size
);
self
.write_primval
(
dest
,
size_val
)
?
;
}
...
...
@@ -414,8 +414,8 @@ fn size_and_align_of_dst(
value
:
Value
,
)
->
EvalResult
<
'tcx
,
(
u64
,
u64
)
>
{
let
pointer_size
=
self
.memory
.pointer_size
();
if
let
Some
(
size
)
=
self
.type_size
(
ty
)
{
Ok
((
size
as
u64
,
self
.type_align
(
ty
)
as
u64
))
if
let
Some
(
size
)
=
self
.type_size
(
ty
)
?
{
Ok
((
size
as
u64
,
self
.type_align
(
ty
)
?
as
u64
))
}
else
{
match
ty
.sty
{
ty
::
TyAdt
(
def
,
substs
)
=>
{
...
...
@@ -424,7 +424,7 @@ fn size_and_align_of_dst(
// and it also rounds up to alignment, which we want to avoid,
// as the unsized field's alignment could be smaller.
assert
!
(
!
ty
.is_simd
());
let
layout
=
self
.type_layout
(
ty
);
let
layout
=
self
.type_layout
(
ty
)
?
;
debug!
(
"DST {} layout: {:?}"
,
ty
,
layout
);
let
(
sized_size
,
sized_align
)
=
match
*
layout
{
...
...
@@ -489,9 +489,9 @@ fn size_and_align_of_dst(
ty
::
TySlice
(
_
)
|
ty
::
TyStr
=>
{
let
elem_ty
=
ty
.sequence_element_type
(
self
.tcx
);
let
elem_size
=
self
.type_size
(
elem_ty
)
.expect
(
"slice element must be sized"
)
as
u64
;
let
elem_size
=
self
.type_size
(
elem_ty
)
?
.expect
(
"slice element must be sized"
)
as
u64
;
let
(
_
,
len
)
=
value
.expect_slice
(
&
self
.memory
)
?
;
let
align
=
self
.type_align
(
elem_ty
);
let
align
=
self
.type_align
(
elem_ty
)
?
;
Ok
((
len
*
elem_size
,
align
as
u64
))
}
...
...
src/interpreter/terminator/mod.rs
浏览文件 @
986b3a07
...
...
@@ -183,7 +183,7 @@ fn eval_fn_call(
match
fn_ty
.abi
{
Abi
::
RustIntrinsic
=>
{
let
ty
=
fn_ty
.sig
.0
.output
;
let
layout
=
self
.type_layout
(
ty
);
let
layout
=
self
.type_layout
(
ty
)
?
;
let
(
ret
,
target
)
=
destination
.unwrap
();
self
.call_intrinsic
(
def_id
,
substs
,
arg_operands
,
ret
,
ty
,
layout
,
target
)
?
;
Ok
(())
...
...
@@ -191,7 +191,7 @@ fn eval_fn_call(
Abi
::
C
=>
{
let
ty
=
fn_ty
.sig
.0
.output
;
let
size
=
self
.type_size
(
ty
)
.expect
(
"function return type cannot be unsized"
);
let
size
=
self
.type_size
(
ty
)
?
.expect
(
"function return type cannot be unsized"
);
let
(
ret
,
target
)
=
destination
.unwrap
();
self
.call_c_abi
(
def_id
,
arg_operands
,
ret
,
size
)
?
;
self
.goto_block
(
target
);
...
...
@@ -248,7 +248,7 @@ fn eval_fn_call(
fn
read_discriminant_value
(
&
self
,
adt_ptr
:
Pointer
,
adt_ty
:
Ty
<
'tcx
>
)
->
EvalResult
<
'tcx
,
u64
>
{
use
rustc
::
ty
::
layout
::
Layout
::
*
;
let
adt_layout
=
self
.type_layout
(
adt_ty
);
let
adt_layout
=
self
.type_layout
(
adt_ty
)
?
;
trace!
(
"read_discriminant_value {:?}"
,
adt_layout
);
let
discr_val
=
match
*
adt_layout
{
...
...
@@ -273,7 +273,7 @@ fn read_discriminant_value(&self, adt_ptr: Pointer, adt_ty: Ty<'tcx>) -> EvalRes
let
nonnull
=
adt_ptr
.offset
(
offset
.bytes
()
as
isize
);
trace!
(
"struct wrapped nullable pointer type: {}"
,
ty
);
// only the pointer part of a fat pointer is used for this space optimization
let
discr_size
=
self
.type_size
(
ty
)
.expect
(
"bad StructWrappedNullablePointer discrfield"
);
let
discr_size
=
self
.type_size
(
ty
)
?
.expect
(
"bad StructWrappedNullablePointer discrfield"
);
self
.read_nonnull_discriminant_value
(
nonnull
,
nndiscr
,
discr_size
)
?
}
...
...
@@ -402,9 +402,9 @@ pub(super) fn fulfill_obligation(&self, trait_ref: ty::PolyTraitRef<'tcx>) -> tr
})
}
fn
unpack_fn_args
(
&
self
,
args
:
&
mut
Vec
<
(
Value
,
Ty
<
'tcx
>
)
>
)
{
fn
unpack_fn_args
(
&
self
,
args
:
&
mut
Vec
<
(
Value
,
Ty
<
'tcx
>
)
>
)
->
EvalResult
<
'tcx
,
()
>
{
if
let
Some
((
last
,
last_ty
))
=
args
.pop
()
{
let
last_layout
=
self
.type_layout
(
last_ty
);
let
last_layout
=
self
.type_layout
(
last_ty
)
?
;
match
(
&
last_ty
.sty
,
last_layout
)
{
(
&
ty
::
TyTuple
(
fields
),
&
Layout
::
Univariant
{
ref
variant
,
..
})
=>
{
...
...
@@ -421,6 +421,7 @@ fn unpack_fn_args(&self, args: &mut Vec<(Value, Ty<'tcx>)>) {
ty
=>
bug!
(
"expected tuple as last argument in function with 'rust-call' ABI, got {:?}"
,
ty
),
}
}
Ok
(())
}
/// Trait method, which has to be resolved to an impl method.
...
...
@@ -452,7 +453,7 @@ fn trait_method(
.expect
(
"The substitutions should have no type parameters remaining after passing through fulfill_obligation"
);
let
closure_kind
=
self
.tcx
.closure_kind
(
vtable_closure
.closure_def_id
);
trace!
(
"closures {:?}, {:?}"
,
closure_kind
,
trait_closure_kind
);
self
.unpack_fn_args
(
args
);
self
.unpack_fn_args
(
args
)
?
;
match
(
closure_kind
,
trait_closure_kind
)
{
(
ty
::
ClosureKind
::
Fn
,
ty
::
ClosureKind
::
Fn
)
|
(
ty
::
ClosureKind
::
FnMut
,
ty
::
ClosureKind
::
FnMut
)
|
...
...
@@ -487,7 +488,7 @@ fn trait_method(
traits
::
VtableFnPointer
(
vtable_fn_ptr
)
=>
{
if
let
ty
::
TyFnDef
(
did
,
ref
substs
,
_
)
=
vtable_fn_ptr
.fn_ty.sty
{
args
.remove
(
0
);
self
.unpack_fn_args
(
args
);
self
.unpack_fn_args
(
args
)
?
;
Ok
((
did
,
substs
))
}
else
{
bug!
(
"VtableFnPointer did not contain a concrete function: {:?}"
,
vtable_fn_ptr
)
...
...
@@ -583,7 +584,7 @@ pub fn drop(
if
let
Some
(
drop_def_id
)
=
adt_def
.destructor
()
{
drop
.push
((
drop_def_id
,
Value
::
ByVal
(
PrimVal
::
from_ptr
(
adt_ptr
)),
substs
));
}
let
layout
=
self
.type_layout
(
ty
);
let
layout
=
self
.type_layout
(
ty
)
?
;
let
fields
=
match
*
layout
{
Layout
::
Univariant
{
ref
variant
,
..
}
=>
{
adt_def
.struct_variant
()
.fields
.iter
()
.zip
(
&
variant
.offsets
)
...
...
@@ -630,7 +631,7 @@ pub fn drop(
)
?
;
},
ty
::
TyTuple
(
fields
)
=>
{
let
offsets
=
match
*
self
.type_layout
(
ty
)
{
let
offsets
=
match
*
self
.type_layout
(
ty
)
?
{
Layout
::
Univariant
{
ref
variant
,
..
}
=>
&
variant
.offsets
,
_
=>
bug!
(
"tuples must be univariant"
),
};
...
...
@@ -658,7 +659,7 @@ pub fn drop(
Lvalue
::
Ptr
{
ptr
,
extra
:
LvalueExtra
::
Length
(
len
)
}
=>
(
ptr
,
len
as
isize
),
_
=>
bug!
(
"expected an lvalue with a length"
),
};
let
size
=
self
.type_size
(
elem_ty
)
.expect
(
"slice element must be sized"
)
as
isize
;
let
size
=
self
.type_size
(
elem_ty
)
?
.expect
(
"slice element must be sized"
)
as
isize
;
// FIXME: this creates a lot of stack frames if the element type has
// a drop impl
for
i
in
0
..
len
{
...
...
@@ -671,7 +672,7 @@ pub fn drop(
Lvalue
::
Ptr
{
ptr
,
extra
}
=>
(
ptr
,
extra
),
_
=>
bug!
(
"expected an lvalue with optional extra data"
),
};
let
size
=
self
.type_size
(
elem_ty
)
.expect
(
"array element cannot be unsized"
)
as
isize
;
let
size
=
self
.type_size
(
elem_ty
)
?
.expect
(
"array element cannot be unsized"
)
as
isize
;
// FIXME: this creates a lot of stack frames if the element type has
// a drop impl
for
i
in
0
..
len
{
...
...
src/interpreter/vtable.rs
浏览文件 @
986b3a07
...
...
@@ -80,8 +80,8 @@ pub fn get_vtable(&mut self, trait_ref: ty::PolyTraitRef<'tcx>) -> EvalResult<'t
}
})
.collect
();
let
size
=
self
.type_size
(
trait_ref
.self_ty
())
.expect
(
"can't create a vtable for an unsized type"
);
let
align
=
self
.type_align
(
trait_ref
.self_ty
());
let
size
=
self
.type_size
(
trait_ref
.self_ty
())
?
.expect
(
"can't create a vtable for an unsized type"
);
let
align
=
self
.type_align
(
trait_ref
.self_ty
())
?
;
let
ptr_size
=
self
.memory
.pointer_size
();
let
vtable
=
self
.memory
.allocate
(
ptr_size
*
(
3
+
methods
.len
()),
ptr_size
)
?
;
...
...
src/memory.rs
浏览文件 @
986b3a07
...
...
@@ -212,7 +212,7 @@ pub fn reallocate(&mut self, ptr: Pointer, new_size: usize, align: usize) -> Eva
if
ptr
.points_to_zst
()
{
return
self
.allocate
(
new_size
,
align
);
}
if
self
.get
(
ptr
.alloc_id
)
.map
(|
alloc
|
alloc
.immutable
)
==
Ok
(
true
)
{
if
self
.get
(
ptr
.alloc_id
)
.map
(|
alloc
|
alloc
.immutable
)
.ok
()
==
Some
(
true
)
{
return
Err
(
EvalError
::
ReallocatedFrozenMemory
);
}
...
...
@@ -245,7 +245,7 @@ pub fn deallocate(&mut self, ptr: Pointer) -> EvalResult<'tcx, ()> {
// TODO(solson): Report error about non-__rust_allocate'd pointer.
return
Err
(
EvalError
::
Unimplemented
(
format!
(
"bad pointer offset: {}"
,
ptr
.offset
)));
}
if
self
.get
(
ptr
.alloc_id
)
.map
(|
alloc
|
alloc
.immutable
)
==
Ok
(
true
)
{
if
self
.get
(
ptr
.alloc_id
)
.map
(|
alloc
|
alloc
.immutable
)
.ok
()
==
Some
(
true
)
{
return
Err
(
EvalError
::
DeallocatedFrozenMemory
);
}
...
...
tests/compile-fail/repeat.rs
0 → 100644
浏览文件 @
986b3a07
fn
main
()
{
let
data
:
[
u8
;
std
::
isize
::
MAX
as
usize
]
=
[
42
;
std
::
isize
::
MAX
as
usize
];
//~^ ERROR: rustc layout computation failed: SizeOverflow([u8;
assert_eq!
(
data
.len
(),
1024
);
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录