Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
14ff6411
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,发现更多精彩内容 >>
未验证
提交
14ff6411
编写于
11月 15, 2016
作者:
O
Oliver Schneider
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
make sure ByVal pointers act just like ByRef to a pointer
上级
4a39c228
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
77 addition
and
88 deletion
+77
-88
src/interpreter/cast.rs
src/interpreter/cast.rs
+1
-4
src/interpreter/mod.rs
src/interpreter/mod.rs
+17
-23
src/interpreter/terminator/intrinsics.rs
src/interpreter/terminator/intrinsics.rs
+8
-6
src/interpreter/terminator/mod.rs
src/interpreter/terminator/mod.rs
+7
-7
src/interpreter/value.rs
src/interpreter/value.rs
+14
-17
src/memory.rs
src/memory.rs
+2
-2
src/primval.rs
src/primval.rs
+21
-29
tests/compile-fail/cast_int_to_fn_ptr.rs
tests/compile-fail/cast_int_to_fn_ptr.rs
+7
-0
未找到文件。
src/interpreter/cast.rs
浏览文件 @
14ff6411
...
...
@@ -21,10 +21,7 @@ pub(super) fn cast_primval(&self, val: PrimVal, ty: Ty<'tcx>) -> EvalResult<'tcx
Bool
|
Char
|
U8
|
U16
|
U32
|
U64
=>
self
.cast_int
(
val
.bits
,
ty
,
false
),
FnPtr
|
Ptr
=>
{
let
ptr
=
val
.expect_ptr
(
"FnPtr- or Ptr-tagged PrimVal had no relocation"
);
self
.cast_ptr
(
ptr
,
ty
)
}
FnPtr
|
Ptr
=>
self
.cast_ptr
(
val
.to_ptr
(),
ty
),
}
}
...
...
src/interpreter/mod.rs
浏览文件 @
14ff6411
...
...
@@ -963,33 +963,27 @@ fn eval_lvalue_projection(
}
Deref
=>
{
use
interpreter
::
value
::
Value
::
*
;
let
val
=
self
.eval_and_read_lvalue
(
&
proj
.base
)
?
;
let
val
=
match
self
.eval_and_read_lvalue
(
&
proj
.base
)
?
{
ByRef
(
ptr
)
=>
self
.read_value
(
ptr
,
base_ty
)
?
,
v
=>
v
,
let
pointee_type
=
match
base_ty
.sty
{
ty
::
TyRawPtr
(
ty
::
TypeAndMut
{
ty
,
..
})
|
ty
::
TyRef
(
_
,
ty
::
TypeAndMut
{
ty
,
..
})
|
ty
::
TyBox
(
ty
)
=>
ty
,
_
=>
bug!
(
"can only deref pointer types"
),
};
match
val
{
ByValPair
(
ptr
,
vtable
)
if
ptr
.try_as_ptr
()
.is_some
()
&&
vtable
.try_as_ptr
()
.is_some
()
=>
{
let
ptr
=
ptr
.try_as_ptr
()
.unwrap
();
let
vtable
=
vtable
.try_as_ptr
()
.unwrap
();
(
ptr
,
LvalueExtra
::
Vtable
(
vtable
))
}
ByValPair
(
ptr
,
n
)
if
ptr
.try_as_ptr
()
.is_some
()
=>
{
let
ptr
=
ptr
.try_as_ptr
()
.unwrap
();
(
ptr
,
LvalueExtra
::
Length
(
n
.expect_uint
(
"slice length"
)))
}
trace!
(
"deref to {} on {:?}"
,
pointee_type
,
val
);
ByVal
(
ptr
)
if
ptr
.try_as_ptr
()
.is_some
()
=>
{
let
ptr
=
ptr
.try_as_ptr
()
.unwrap
();
(
ptr
,
LvalueExtra
::
None
)
}
_
=>
bug!
(
"can't deref non pointer types"
),
match
self
.tcx
.struct_tail
(
pointee_type
)
.sty
{
ty
::
TyTrait
(
_
)
=>
{
let
(
ptr
,
vtable
)
=
val
.expect_ptr_vtable_pair
(
&
self
.memory
)
?
;
(
ptr
,
LvalueExtra
::
Vtable
(
vtable
))
},
ty
::
TyStr
|
ty
::
TySlice
(
_
)
=>
{
let
(
ptr
,
len
)
=
val
.expect_slice
(
&
self
.memory
)
?
;
(
ptr
,
LvalueExtra
::
Length
(
len
))
},
_
=>
(
val
.read_ptr
(
&
self
.memory
)
?
,
LvalueExtra
::
None
),
}
}
...
...
src/interpreter/terminator/intrinsics.rs
浏览文件 @
14ff6411
...
...
@@ -124,15 +124,17 @@ pub(super) fn call_intrinsic(
"drop_in_place"
=>
{
let
ty
=
substs
.type_at
(
0
);
trace!
(
"drop in place on {}"
,
ty
);
let
ptr_ty
=
self
.tcx
.mk_mut_ptr
(
ty
);
let
lvalue
=
match
self
.follow_by_ref_value
(
arg_vals
[
0
],
ptr_ty
)
?
{
Value
::
ByRef
(
_
)
=>
bug!
(
"follow_by_ref_value returned ByRef"
),
Value
::
ByVal
(
ptr
)
=>
Lvalue
::
from_ptr
(
ptr
.expect_ptr
(
"drop_in_place first arg not a pointer"
)),
Value
::
ByVal
(
value
)
=>
Lvalue
::
from_ptr
(
value
.to_ptr
(
)),
Value
::
ByValPair
(
ptr
,
extra
)
=>
Lvalue
::
Ptr
{
ptr
:
ptr
.expect_ptr
(
"drop_in_place first arg not a pointer"
),
extra
:
match
extra
.try_as_ptr
()
{
Some
(
vtable
)
=>
LvalueExtra
::
Vtable
(
vtable
),
None
=>
LvalueExtra
::
Length
(
extra
.expect_uint
(
"either pointer or not, but not neither"
)),
ptr
:
ptr
.to_ptr
(),
extra
:
match
self
.tcx
.struct_tail
(
ty
)
.sty
{
ty
::
TyTrait
(
_
)
=>
LvalueExtra
::
Vtable
(
extra
.to_ptr
()),
ty
::
TyStr
|
ty
::
TySlice
(
_
)
=>
LvalueExtra
::
Length
(
extra
.try_as_uint
()
?
),
_
=>
bug!
(
"invalid fat pointer type: {}"
,
ptr_ty
),
},
},
};
...
...
@@ -440,7 +442,7 @@ 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
len
=
value
.expect_slice_len
(
&
self
.memory
)
?
;
let
(
_
,
len
)
=
value
.expect_slice
(
&
self
.memory
)
?
;
let
align
=
self
.type_align
(
elem_ty
);
Ok
((
len
*
elem_size
,
align
as
u64
))
}
...
...
src/interpreter/terminator/mod.rs
浏览文件 @
14ff6411
...
...
@@ -85,8 +85,7 @@ pub(super) fn eval_terminator(
let
func_ty
=
self
.operand_ty
(
func
);
match
func_ty
.sty
{
ty
::
TyFnPtr
(
bare_fn_ty
)
=>
{
let
fn_ptr
=
self
.eval_operand_to_primval
(
func
)
?
.expect_fn_ptr
(
"TyFnPtr callee did not evaluate to FnPtr"
);
let
fn_ptr
=
self
.eval_operand_to_primval
(
func
)
?
.to_ptr
();
let
(
def_id
,
substs
,
fn_ty
)
=
self
.memory
.get_fn
(
fn_ptr
.alloc_id
)
?
;
if
fn_ty
!=
bare_fn_ty
{
return
Err
(
EvalError
::
FunctionPointerTyMismatch
(
fn_ty
,
bare_fn_ty
));
...
...
@@ -542,14 +541,15 @@ fn drop(
Value
::
ByRef
(
_
)
=>
bug!
(
"follow_by_ref_value can't result in ByRef"
),
Value
::
ByVal
(
ptr
)
=>
{
assert
!
(
self
.type_is_sized
(
contents_ty
));
let
contents_ptr
=
ptr
.
expect_ptr
(
"value of Box type must be a pointer"
);
let
contents_ptr
=
ptr
.
to_ptr
(
);
self
.drop
(
Lvalue
::
from_ptr
(
contents_ptr
),
contents_ty
,
drop
)
?
;
},
Value
::
ByValPair
(
prim_ptr
,
extra
)
=>
{
let
ptr
=
prim_ptr
.expect_ptr
(
"value of Box type must be a pointer"
);
let
extra
=
match
extra
.try_as_ptr
()
{
Some
(
vtable
)
=>
LvalueExtra
::
Vtable
(
vtable
),
None
=>
LvalueExtra
::
Length
(
extra
.expect_uint
(
"slice length"
)),
let
ptr
=
prim_ptr
.to_ptr
();
let
extra
=
match
self
.tcx
.struct_tail
(
contents_ty
)
.sty
{
ty
::
TyTrait
(
_
)
=>
LvalueExtra
::
Vtable
(
extra
.to_ptr
()),
ty
::
TyStr
|
ty
::
TySlice
(
_
)
=>
LvalueExtra
::
Length
(
extra
.try_as_uint
()
?
),
_
=>
bug!
(
"invalid fat pointer type: {}"
,
ty
),
};
self
.drop
(
Lvalue
::
Ptr
{
...
...
src/interpreter/value.rs
浏览文件 @
14ff6411
...
...
@@ -22,10 +22,7 @@ pub(super) fn read_ptr(&self, mem: &Memory<'a, 'tcx>) -> EvalResult<'tcx, Pointe
use
self
::
Value
::
*
;
match
*
self
{
ByRef
(
ptr
)
=>
mem
.read_ptr
(
ptr
),
ByVal
(
ptr
)
|
ByValPair
(
ptr
,
_
)
=>
{
Ok
(
ptr
.try_as_ptr
()
.expect
(
"unimplemented: `read_ptr` on non-ptr primval"
))
}
ByVal
(
ptr
)
|
ByValPair
(
ptr
,
_
)
=>
Ok
(
ptr
.to_ptr
()),
}
}
...
...
@@ -35,29 +32,29 @@ pub(super) fn expect_ptr_vtable_pair(
)
->
EvalResult
<
'tcx
,
(
Pointer
,
Pointer
)
>
{
use
self
::
Value
::
*
;
match
*
self
{
ByRef
(
ptr
)
=>
{
let
ptr
=
mem
.read_ptr
(
ptr
)
?
;
let
vtable
=
mem
.read_ptr
(
ptr
.offset
(
mem
.pointer_size
()
as
isize
))
?
;
ByRef
(
ref_
ptr
)
=>
{
let
ptr
=
mem
.read_ptr
(
ref_
ptr
)
?
;
let
vtable
=
mem
.read_ptr
(
ref_
ptr
.offset
(
mem
.pointer_size
()
as
isize
))
?
;
Ok
((
ptr
,
vtable
))
}
ByValPair
(
ptr
,
vtable
)
if
ptr
.try_as_ptr
()
.is_some
()
&&
vtable
.try_as_ptr
()
.is_some
()
=>
{
let
ptr
=
ptr
.try_as_ptr
()
.unwrap
();
let
vtable
=
vtable
.try_as_ptr
()
.unwrap
();
Ok
((
ptr
,
vtable
))
}
ByValPair
(
ptr
,
vtable
)
=>
Ok
((
ptr
.to_ptr
(),
vtable
.to_ptr
())),
_
=>
bug!
(
"expected ptr and vtable, got {:?}"
,
self
),
}
}
pub
(
super
)
fn
expect_slice
_len
(
&
self
,
mem
:
&
Memory
<
'a
,
'tcx
>
)
->
EvalResult
<
'tcx
,
u64
>
{
pub
(
super
)
fn
expect_slice
(
&
self
,
mem
:
&
Memory
<
'a
,
'tcx
>
)
->
EvalResult
<
'tcx
,
(
Pointer
,
u64
)
>
{
use
self
::
Value
::
*
;
match
*
self
{
ByRef
(
ptr
)
=>
mem
.read_usize
(
ptr
.offset
(
mem
.pointer_size
()
as
isize
)),
ByValPair
(
_
,
val
)
if
val
.kind
.is_int
()
=>
Ok
(
val
.bits
),
ByRef
(
ref_ptr
)
=>
{
let
ptr
=
mem
.read_ptr
(
ref_ptr
)
?
;
let
len
=
mem
.read_usize
(
ref_ptr
.offset
(
mem
.pointer_size
()
as
isize
))
?
;
Ok
((
ptr
,
len
))
},
ByValPair
(
ptr
,
val
)
=>
{
Ok
((
ptr
.to_ptr
(),
val
.try_as_uint
()
?
))
},
_
=>
unimplemented!
(),
}
}
...
...
src/memory.rs
浏览文件 @
14ff6411
...
...
@@ -533,8 +533,8 @@ pub fn write_ptr(&mut self, dest: Pointer, ptr: Pointer) -> EvalResult<'tcx, ()>
}
pub
fn
write_primval
(
&
mut
self
,
dest
:
Pointer
,
val
:
PrimVal
)
->
EvalResult
<
'tcx
,
()
>
{
if
let
Some
(
ptr
)
=
val
.try_as_ptr
()
{
return
self
.write_ptr
(
dest
,
ptr
);
if
let
Some
(
alloc_id
)
=
val
.relocation
{
return
self
.write_ptr
(
dest
,
Pointer
::
new
(
alloc_id
,
val
.bits
as
usize
)
);
}
use
primval
::
PrimValKind
::
*
;
...
...
src/primval.rs
浏览文件 @
14ff6411
...
...
@@ -137,15 +137,19 @@ pub fn to_f64(self) -> f64 {
bits_to_f64
(
self
.bits
)
}
pub
fn
t
ry_as_ptr
(
self
)
->
Option
<
Pointer
>
{
pub
fn
t
o_ptr
(
self
)
->
Pointer
{
self
.relocation
.map
(|
alloc_id
|
{
Pointer
::
new
(
alloc_id
,
self
.bits
as
usize
)
})
})
.unwrap_or_else
(||
Pointer
::
from_int
(
self
.bits
as
usize
))
}
pub
fn
try_as_uint
<
'tcx
>
(
self
)
->
EvalResult
<
'tcx
,
u64
>
{
self
.to_ptr
()
.to_int
()
.map
(|
val
|
val
as
u64
)
}
pub
fn
expect_uint
(
self
,
error_msg
:
&
str
)
->
u64
{
if
let
Some
(
ptr
)
=
self
.try_as_ptr
()
{
return
ptr
.to_int
()
.expect
(
"non abstract ptr"
)
as
u64
if
let
Ok
(
int
)
=
self
.try_as_uint
()
{
return
int
;
}
use
self
::
PrimValKind
::
*
;
...
...
@@ -156,8 +160,8 @@ pub fn expect_uint(self, error_msg: &str) -> u64 {
}
pub
fn
expect_int
(
self
,
error_msg
:
&
str
)
->
i64
{
if
let
Some
(
ptr
)
=
self
.try_as_ptr
()
{
return
ptr
.to_int
()
.expect
(
"non abstract ptr"
)
as
i64
if
let
Ok
(
int
)
=
self
.try_as_uint
()
{
return
int
as
i64
;
}
use
self
::
PrimValKind
::
*
;
...
...
@@ -188,15 +192,6 @@ pub fn expect_f64(self, error_msg: &str) -> f64 {
_
=>
bug!
(
"{}"
,
error_msg
),
}
}
pub
fn
expect_ptr
(
self
,
error_msg
:
&
str
)
->
Pointer
{
self
.try_as_ptr
()
.expect
(
error_msg
)
}
/// FIXME(solson): Refactored into a duplicate of `expect_ptr`. Investigate removal.
pub
fn
expect_fn_ptr
(
self
,
error_msg
:
&
str
)
->
Pointer
{
self
.try_as_ptr
()
.expect
(
error_msg
)
}
}
////////////////////////////////////////////////////////////////////////////////
...
...
@@ -277,19 +272,13 @@ pub fn binary_op<'tcx>(
use
rustc
::
mir
::
BinOp
::
*
;
use
self
::
PrimValKind
::
*
;
match
(
left
.try_as_ptr
(),
right
.try_as_ptr
())
{
(
Some
(
left_ptr
),
Some
(
right_ptr
))
=>
{
if
left_ptr
.alloc_id
!=
right_ptr
.alloc_id
{
return
Ok
((
unrelated_ptr_ops
(
bin_op
)
?
,
false
));
}
// If the pointers are into the same allocation, fall through to the more general match
// later, which will do comparisons on the `bits` fields, which are the pointer offsets
// in this case.
}
(
None
,
None
)
=>
{}
_
=>
return
Err
(
EvalError
::
ReadPointerAsBytes
),
// If the pointers are into the same allocation, fall through to the more general match
// later, which will do comparisons on the `bits` fields, which are the pointer offsets
// in this case.
let
left_ptr
=
left
.to_ptr
();
let
right_ptr
=
right
.to_ptr
();
if
left_ptr
.alloc_id
!=
right_ptr
.alloc_id
{
return
Ok
((
unrelated_ptr_ops
(
bin_op
,
left_ptr
,
right_ptr
)
?
,
false
));
}
let
(
l
,
r
)
=
(
left
.bits
,
right
.bits
);
...
...
@@ -376,12 +365,15 @@ pub fn binary_op<'tcx>(
Ok
((
val
,
false
))
}
fn
unrelated_ptr_ops
<
'tcx
>
(
bin_op
:
mir
::
BinOp
)
->
EvalResult
<
'tcx
,
PrimVal
>
{
fn
unrelated_ptr_ops
<
'tcx
>
(
bin_op
:
mir
::
BinOp
,
left
:
Pointer
,
right
:
Pointer
)
->
EvalResult
<
'tcx
,
PrimVal
>
{
use
rustc
::
mir
::
BinOp
::
*
;
match
bin_op
{
Eq
=>
Ok
(
PrimVal
::
from_bool
(
false
)),
Ne
=>
Ok
(
PrimVal
::
from_bool
(
true
)),
Lt
|
Le
|
Gt
|
Ge
=>
Err
(
EvalError
::
InvalidPointerMath
),
_
if
left
.to_int
()
.is_ok
()
^
right
.to_int
()
.is_ok
()
=>
{
Err
(
EvalError
::
ReadPointerAsBytes
)
},
_
=>
bug!
(),
}
}
...
...
tests/compile-fail/cast_int_to_fn_ptr.rs
0 → 100644
浏览文件 @
14ff6411
fn
main
()
{
let
g
=
unsafe
{
std
::
mem
::
transmute
::
<
usize
,
fn
(
i32
)
>
(
42
)
};
g
(
42
)
//~ ERROR tried to use an integer pointer or a dangling pointer as a function pointer
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录