Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
6ec3d650
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,发现更多精彩内容 >>
提交
6ec3d650
编写于
12月 16, 2016
作者:
S
Scott Olson
提交者:
GitHub
12月 16, 2016
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Revert "Revert "rustup to rustc 1.15.0-dev (
ace092f5
2016-12-13)""
上级
f789c40e
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
97 addition
and
78 deletion
+97
-78
src/bin/miri.rs
src/bin/miri.rs
+12
-10
src/error.rs
src/error.rs
+3
-0
src/memory.rs
src/memory.rs
+16
-0
src/terminator/intrinsic.rs
src/terminator/intrinsic.rs
+1
-0
src/terminator/mod.rs
src/terminator/mod.rs
+45
-10
tests/compiletest.rs
tests/compiletest.rs
+12
-58
tests/run-pass/aux_test.rs
tests/run-pass/aux_test.rs
+7
-0
tests/run-pass/auxiliary/dep.rs
tests/run-pass/auxiliary/dep.rs
+1
-0
未找到文件。
src/bin/miri.rs
浏览文件 @
6ec3d650
...
...
@@ -10,7 +10,7 @@
#[macro_use]
extern
crate
log
;
use
rustc
::
session
::
Session
;
use
rustc_driver
::
{
CompilerCalls
,
Compilation
}
;
use
rustc_driver
::
CompilerCalls
;
use
rustc_driver
::
driver
::{
CompileState
,
CompileController
};
use
syntax
::
ast
::{
MetaItemKind
,
NestedMetaItemKind
};
...
...
@@ -21,7 +21,6 @@ fn build_controller(&mut self, _: &Session, _: &getopts::Matches) -> CompileCont
let
mut
control
=
CompileController
::
basic
();
control
.after_hir_lowering.callback
=
Box
::
new
(
after_hir_lowering
);
control
.after_analysis.callback
=
Box
::
new
(
after_analysis
);
control
.after_analysis.stop
=
Compilation
::
Stop
;
control
}
}
...
...
@@ -35,14 +34,16 @@ fn after_analysis(state: &mut CompileState) {
state
.session
.abort_if_errors
();
let
tcx
=
state
.tcx
.unwrap
();
let
(
entry_node_id
,
_
)
=
state
.session.entry_fn
.borrow
()
.expect
(
"no main or start function found"
);
let
entry_def_id
=
tcx
.map
.local_def_id
(
entry_node_id
);
let
limits
=
resource_limits_from_attributes
(
state
);
miri
::
run_mir_passes
(
tcx
);
miri
::
eval_main
(
tcx
,
entry_def_id
,
limits
);
state
.session
.abort_if_errors
();
if
let
Some
((
entry_node_id
,
_
))
=
*
state
.session.entry_fn
.borrow
()
{
let
entry_def_id
=
tcx
.map
.local_def_id
(
entry_node_id
);
let
limits
=
resource_limits_from_attributes
(
state
);
miri
::
run_mir_passes
(
tcx
);
miri
::
eval_main
(
tcx
,
entry_def_id
,
limits
);
state
.session
.abort_if_errors
();
}
else
{
println!
(
"no main function found, assuming auxiliary build"
);
}
}
fn
resource_limits_from_attributes
(
state
:
&
CompileState
)
->
miri
::
ResourceLimits
{
...
...
@@ -134,6 +135,7 @@ fn main() {
args
.push
(
sysroot_flag
);
args
.push
(
find_sysroot
());
}
args
.push
(
"-Zalways-encode-mir"
.to_owned
());
rustc_driver
::
run_compiler
(
&
args
,
&
mut
MiriCompilerCalls
,
None
,
None
);
}
src/error.rs
浏览文件 @
6ec3d650
...
...
@@ -11,6 +11,7 @@
pub
enum
EvalError
<
'tcx
>
{
FunctionPointerTyMismatch
(
Abi
,
&
'tcx
FnSig
<
'tcx
>
,
&
'tcx
BareFnTy
<
'tcx
>
),
NoMirFor
(
String
),
UnterminatedCString
(
Pointer
),
DanglingPointerDeref
,
InvalidMemoryAccess
,
InvalidFunctionPointer
,
...
...
@@ -119,6 +120,8 @@ fn description(&self) -> &str {
"tried to deallocate frozen memory"
,
EvalError
::
Layout
(
_
)
=>
"rustc layout computation failed"
,
EvalError
::
UnterminatedCString
(
_
)
=>
"attempted to get length of a null terminated string, but no null found before end of allocation"
,
}
}
...
...
src/memory.rs
浏览文件 @
6ec3d650
...
...
@@ -530,6 +530,22 @@ pub fn copy(&mut self, src: Pointer, dest: Pointer, size: u64, align: u64) -> Ev
Ok
(())
}
pub
fn
read_c_str
(
&
self
,
ptr
:
Pointer
)
->
EvalResult
<
'tcx
,
&
[
u8
]
>
{
let
alloc
=
self
.get
(
ptr
.alloc_id
)
?
;
assert_eq!
(
ptr
.offset
as
usize
as
u64
,
ptr
.offset
);
let
offset
=
ptr
.offset
as
usize
;
match
alloc
.bytes
[
offset
..
]
.iter
()
.position
(|
&
c
|
c
==
0
)
{
Some
(
size
)
=>
{
if
self
.relocations
(
ptr
,
(
size
+
1
)
as
u64
)
?
.count
()
!=
0
{
return
Err
(
EvalError
::
ReadPointerAsBytes
);
}
self
.check_defined
(
ptr
,
(
size
+
1
)
as
u64
)
?
;
Ok
(
&
alloc
.bytes
[
offset
..
offset
+
size
])
},
None
=>
Err
(
EvalError
::
UnterminatedCString
(
ptr
)),
}
}
pub
fn
read_bytes
(
&
self
,
ptr
:
Pointer
,
size
:
u64
)
->
EvalResult
<
'tcx
,
&
[
u8
]
>
{
self
.get_bytes
(
ptr
,
size
,
1
)
}
...
...
src/terminator/intrinsic.rs
浏览文件 @
6ec3d650
...
...
@@ -57,6 +57,7 @@ pub(super) fn call_intrinsic(
}
"atomic_load"
|
"atomic_load_relaxed"
|
"atomic_load_acq"
|
"volatile_load"
=>
{
let
ty
=
substs
.type_at
(
0
);
...
...
src/terminator/mod.rs
浏览文件 @
6ec3d650
...
...
@@ -90,7 +90,16 @@ pub(super) fn eval_terminator(
ty
::
TyFnPtr
(
bare_fn_ty
)
=>
{
let
fn_ptr
=
self
.eval_operand_to_primval
(
func
)
?
.to_ptr
();
let
(
def_id
,
substs
,
abi
,
sig
)
=
self
.memory
.get_fn
(
fn_ptr
.alloc_id
)
?
;
if
abi
!=
bare_fn_ty
.abi
||
sig
!=
bare_fn_ty
.sig
.skip_binder
()
{
let
bare_sig
=
self
.tcx
.erase_late_bound_regions_and_normalize
(
&
bare_fn_ty
.sig
);
let
bare_sig
=
self
.tcx
.erase_regions
(
&
bare_sig
);
// transmuting function pointers in miri is fine as long as the number of
// arguments and the abi don't change.
// FIXME: also check the size of the arguments' type and the return type
// Didn't get it to work, since that triggers an assertion in rustc which
// checks whether the type has escaping regions
if
abi
!=
bare_fn_ty
.abi
||
sig
.variadic
!=
bare_sig
.variadic
||
sig
.inputs
()
.len
()
!=
bare_sig
.inputs
()
.len
()
{
return
Err
(
EvalError
::
FunctionPointerTyMismatch
(
abi
,
sig
,
bare_fn_ty
));
}
self
.eval_fn_call
(
def_id
,
substs
,
bare_fn_ty
,
destination
,
args
,
...
...
@@ -189,7 +198,7 @@ fn eval_fn_call(
use
syntax
::
abi
::
Abi
;
match
fn_ty
.abi
{
Abi
::
RustIntrinsic
=>
{
let
ty
=
fn_ty
.sig
.0
.output
;
let
ty
=
fn_ty
.sig
.0
.output
()
;
let
layout
=
self
.type_layout
(
ty
)
?
;
let
(
ret
,
target
)
=
destination
.unwrap
();
self
.call_intrinsic
(
def_id
,
substs
,
arg_operands
,
ret
,
ty
,
layout
,
target
)
?
;
...
...
@@ -197,7 +206,7 @@ fn eval_fn_call(
}
Abi
::
C
=>
{
let
ty
=
fn_ty
.sig
.0
.output
;
let
ty
=
fn_ty
.sig
.0
.output
()
;
let
(
ret
,
target
)
=
destination
.unwrap
();
self
.call_c_abi
(
def_id
,
arg_operands
,
ret
,
ty
)
?
;
self
.goto_block
(
target
);
...
...
@@ -320,11 +329,6 @@ fn call_c_abi(
.collect
();
let
args
=
args_res
?
;
if
link_name
.starts_with
(
"pthread_"
)
{
warn!
(
"ignoring C ABI call: {}"
,
link_name
);
return
Ok
(());
}
let
usize
=
self
.tcx.types.usize
;
match
&
link_name
[
..
]
{
...
...
@@ -371,6 +375,37 @@ fn call_c_abi(
self
.write_primval
(
dest
,
PrimVal
::
new
(
result
as
u64
),
dest_ty
)
?
;
}
"memchr"
=>
{
let
ptr
=
args
[
0
]
.read_ptr
(
&
self
.memory
)
?
;
let
val
=
self
.value_to_primval
(
args
[
1
],
usize
)
?
.to_u64
()
as
u8
;
let
num
=
self
.value_to_primval
(
args
[
2
],
usize
)
?
.to_u64
();
if
let
Some
(
idx
)
=
self
.memory
.read_bytes
(
ptr
,
num
)
?
.iter
()
.position
(|
&
c
|
c
==
val
)
{
let
new_ptr
=
ptr
.offset
(
idx
as
u64
);
self
.write_value
(
Value
::
ByVal
(
PrimVal
::
from_ptr
(
new_ptr
)),
dest
,
dest_ty
)
?
;
}
else
{
self
.write_value
(
Value
::
ByVal
(
PrimVal
::
new
(
0
)),
dest
,
dest_ty
)
?
;
}
}
"getenv"
=>
{
{
let
name_ptr
=
args
[
0
]
.read_ptr
(
&
self
.memory
)
?
;
let
name
=
self
.memory
.read_c_str
(
name_ptr
)
?
;
info!
(
"ignored env var request for `{:?}`"
,
::
std
::
str
::
from_utf8
(
name
));
}
self
.write_value
(
Value
::
ByVal
(
PrimVal
::
new
(
0
)),
dest
,
dest_ty
)
?
;
}
// unix panic code inside libstd will read the return value of this function
"pthread_rwlock_rdlock"
=>
{
self
.write_primval
(
dest
,
PrimVal
::
new
(
0
),
dest_ty
)
?
;
}
link_name
if
link_name
.starts_with
(
"pthread_"
)
=>
{
warn!
(
"ignoring C ABI call: {}"
,
link_name
);
return
Ok
(());
},
_
=>
{
return
Err
(
EvalError
::
Unimplemented
(
format!
(
"can't call C ABI function: {}"
,
link_name
)));
}
...
...
@@ -520,7 +555,7 @@ fn trait_method(
let
offset
=
idx
*
self
.memory
.pointer_size
();
let
fn_ptr
=
self
.memory
.read_ptr
(
vtable
.offset
(
offset
))
?
;
let
(
def_id
,
substs
,
_
abi
,
sig
)
=
self
.memory
.get_fn
(
fn_ptr
.alloc_id
)
?
;
*
first_ty
=
sig
.inputs
[
0
];
*
first_ty
=
sig
.inputs
()
[
0
];
Ok
((
def_id
,
substs
,
Vec
::
new
()))
}
else
{
Err
(
EvalError
::
VtableForArgumentlessMethod
)
...
...
@@ -664,7 +699,7 @@ pub fn drop(
// some values don't need to call a drop impl, so the value is null
if
drop_fn
!=
Pointer
::
from_int
(
0
)
{
let
(
def_id
,
substs
,
_
abi
,
sig
)
=
self
.memory
.get_fn
(
drop_fn
.alloc_id
)
?
;
let
real_ty
=
sig
.inputs
[
0
];
let
real_ty
=
sig
.inputs
()
[
0
];
self
.drop
(
Lvalue
::
from_ptr
(
ptr
),
real_ty
,
drop
)
?
;
drop
.push
((
def_id
,
Value
::
ByVal
(
PrimVal
::
from_ptr
(
ptr
)),
substs
));
}
else
{
...
...
tests/compiletest.rs
浏览文件 @
6ec3d650
...
...
@@ -27,6 +27,15 @@ fn run_pass() {
compiletest
::
run_tests
(
&
config
);
}
fn
miri_pass
(
path
:
&
str
,
target
:
&
str
)
{
let
mut
config
=
compiletest
::
default_config
();
config
.mode
=
"mir-opt"
.parse
()
.expect
(
"Invalid mode"
);
config
.src_base
=
PathBuf
::
from
(
path
);
config
.target
=
target
.to_owned
();
config
.rustc_path
=
PathBuf
::
from
(
"target/debug/miri"
);
compiletest
::
run_tests
(
&
config
);
}
fn
for_all_targets
<
F
:
FnMut
(
String
)
>
(
sysroot
:
&
str
,
mut
f
:
F
)
{
for
target
in
std
::
fs
::
read_dir
(
format!
(
"{}/lib/rustlib/"
,
sysroot
))
.unwrap
()
{
let
target
=
target
.unwrap
();
...
...
@@ -57,65 +66,10 @@ fn compile_test() {
};
run_pass
();
for_all_targets
(
&
sysroot
,
|
target
|
{
let
files
=
std
::
fs
::
read_dir
(
"tests/run-pass"
)
.unwrap
();
let
files
:
Box
<
Iterator
<
Item
=
_
>>
=
if
let
Ok
(
path
)
=
std
::
env
::
var
(
"MIRI_RUSTC_TEST"
)
{
Box
::
new
(
files
.chain
(
std
::
fs
::
read_dir
(
path
)
.unwrap
()))
}
else
{
Box
::
new
(
files
)
};
let
mut
mir_not_found
=
0
;
let
mut
crate_not_found
=
0
;
let
mut
success
=
0
;
let
mut
failed
=
0
;
for
file
in
files
{
let
file
=
file
.unwrap
();
let
path
=
file
.path
();
if
!
file
.metadata
()
.unwrap
()
.is_file
()
||
!
path
.to_str
()
.unwrap
()
.ends_with
(
".rs"
)
{
continue
;
}
let
stderr
=
std
::
io
::
stderr
();
write!
(
stderr
.lock
(),
"test [miri-pass] {} ... "
,
path
.display
())
.unwrap
();
let
mut
cmd
=
std
::
process
::
Command
::
new
(
"target/debug/miri"
);
cmd
.arg
(
path
);
cmd
.arg
(
format!
(
"--target={}"
,
target
));
let
libs
=
Path
::
new
(
&
sysroot
)
.join
(
"lib"
);
let
sysroot
=
libs
.join
(
"rustlib"
)
.join
(
&
target
)
.join
(
"lib"
);
let
paths
=
std
::
env
::
join_paths
(
&
[
libs
,
sysroot
])
.unwrap
();
cmd
.env
(
compiletest
::
procsrv
::
dylib_env_var
(),
paths
);
match
cmd
.output
()
{
Ok
(
ref
output
)
if
output
.status
.success
()
=>
{
success
+=
1
;
writeln!
(
stderr
.lock
(),
"ok"
)
.unwrap
()
},
Ok
(
output
)
=>
{
let
output_err
=
std
::
str
::
from_utf8
(
&
output
.stderr
)
.unwrap
();
if
let
Some
(
text
)
=
output_err
.splitn
(
2
,
"no mir for `"
)
.nth
(
1
)
{
mir_not_found
+=
1
;
let
end
=
text
.find
(
'`'
)
.unwrap
();
writeln!
(
stderr
.lock
(),
"NO MIR FOR `{}`"
,
&
text
[
..
end
])
.unwrap
();
}
else
if
let
Some
(
text
)
=
output_err
.splitn
(
2
,
"can't find crate for `"
)
.nth
(
1
)
{
crate_not_found
+=
1
;
let
end
=
text
.find
(
'`'
)
.unwrap
();
writeln!
(
stderr
.lock
(),
"CAN'T FIND CRATE FOR `{}`"
,
&
text
[
..
end
])
.unwrap
();
}
else
{
failed
+=
1
;
writeln!
(
stderr
.lock
(),
"FAILED with exit code {:?}"
,
output
.status
.code
())
.unwrap
();
writeln!
(
stderr
.lock
(),
"stdout:
\n
{}"
,
std
::
str
::
from_utf8
(
&
output
.stdout
)
.unwrap
())
.unwrap
();
writeln!
(
stderr
.lock
(),
"stderr:
\n
{}"
,
output_err
)
.unwrap
();
}
}
Err
(
e
)
=>
{
writeln!
(
stderr
.lock
(),
"FAILED: {}"
,
e
)
.unwrap
();
panic!
(
"failed to execute miri"
);
},
}
miri_pass
(
"tests/run-pass"
,
&
target
);
if
let
Ok
(
path
)
=
std
::
env
::
var
(
"MIRI_RUSTC_TEST"
)
{
miri_pass
(
&
path
,
&
target
);
}
let
stderr
=
std
::
io
::
stderr
();
writeln!
(
stderr
.lock
(),
"{} success, {} mir not found, {} crate not found, {} failed"
,
success
,
mir_not_found
,
crate_not_found
,
failed
)
.unwrap
();
assert_eq!
(
failed
,
0
,
"some tests failed"
);
});
compile_fail
(
&
sysroot
);
}
tests/run-pass/aux_test.rs
0 → 100644
浏览文件 @
6ec3d650
// aux-build:dep.rs
extern
crate
dep
;
fn
main
()
{
dep
::
foo
();
}
tests/run-pass/auxiliary/dep.rs
0 → 100644
浏览文件 @
6ec3d650
pub
fn
foo
()
{}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录