Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
25e52383
R
Rust
项目概览
int
/
Rust
11 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
25e52383
编写于
3月 27, 2014
作者:
B
bors
浏览文件
操作
浏览文件
下载
差异文件
auto merge of #13001 : cmr/rust/unnamed-lifetime-nocapture, r=nikomatsakis
Closes #6751
上级
e560db7d
5258e13d
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
50 addition
and
3 deletion
+50
-3
src/librustc/middle/trans/base.rs
src/librustc/middle/trans/base.rs
+12
-1
src/librustc/middle/trans/callee.rs
src/librustc/middle/trans/callee.rs
+37
-2
src/test/run-pass/out-of-stack.rs
src/test/run-pass/out-of-stack.rs
+1
-0
未找到文件。
src/librustc/middle/trans/base.rs
浏览文件 @
25e52383
...
...
@@ -246,6 +246,8 @@ fn get_extern_rust_fn(ccx: &CrateContext, inputs: &[ty::t], output: ty::t,
pub
fn
decl_rust_fn
(
ccx
:
&
CrateContext
,
has_env
:
bool
,
inputs
:
&
[
ty
::
t
],
output
:
ty
::
t
,
name
:
&
str
)
->
ValueRef
{
use
middle
::
ty
::{
BrAnon
,
ReLateBound
};
let
llfty
=
type_of_rust_fn
(
ccx
,
has_env
,
inputs
,
output
);
let
llfn
=
decl_cdecl_fn
(
ccx
.llmod
,
name
,
llfty
,
output
);
...
...
@@ -265,7 +267,16 @@ pub fn decl_rust_fn(ccx: &CrateContext, has_env: bool,
unsafe
{
llvm
::
LLVMAddAttribute
(
llarg
,
lib
::
llvm
::
NoAliasAttribute
as
c_uint
);
}
}
},
// When a reference in an argument has no named lifetime, it's
// impossible for that reference to escape this function(ie, be
// returned).
ty
::
ty_rptr
(
ReLateBound
(
_
,
BrAnon
(
_
)),
_
)
=>
{
debug!
(
"marking argument of {} as nocapture because of anonymous lifetime"
,
name
);
unsafe
{
llvm
::
LLVMAddAttribute
(
llarg
,
lib
::
llvm
::
NoCaptureAttribute
as
c_uint
);
}
},
_
=>
{
// For non-immediate arguments the callee gets its own copy of
// the value on the stack, so there are no aliases
...
...
src/librustc/middle/trans/callee.rs
浏览文件 @
25e52383
...
...
@@ -20,7 +20,7 @@
use
back
::
abi
;
use
driver
::
session
;
use
lib
::
llvm
::{
ValueRef
,
NoAliasAttribute
,
StructRetAttribute
};
use
lib
::
llvm
::{
ValueRef
,
NoAliasAttribute
,
StructRetAttribute
,
NoCaptureAttribute
};
use
lib
::
llvm
::
llvm
;
use
metadata
::
csearch
;
use
middle
::
trans
::
base
;
...
...
@@ -661,9 +661,15 @@ pub fn trans_call_inner<'a>(
llargs
.push
(
opt_llretslot
.unwrap
());
}
// start at 1, because index 0 is the return value of the llvm func
let
mut
first_arg_offset
=
1
;
// Push the environment (or a trait object's self).
match
(
llenv
,
llself
)
{
(
Some
(
llenv
),
None
)
=>
llargs
.push
(
llenv
),
(
Some
(
llenv
),
None
)
=>
{
first_arg_offset
+=
1
;
llargs
.push
(
llenv
)
},
(
None
,
Some
(
llself
))
=>
llargs
.push
(
llself
),
_
=>
{}
}
...
...
@@ -682,6 +688,11 @@ pub fn trans_call_inner<'a>(
let
mut
attrs
=
Vec
::
new
();
if
type_of
::
return_uses_outptr
(
ccx
,
ret_ty
)
{
attrs
.push
((
1
,
StructRetAttribute
));
// The outptr can be noalias and nocapture because it's entirely
// invisible to the program.
attrs
.push
((
1
,
NoAliasAttribute
));
attrs
.push
((
1
,
NoCaptureAttribute
));
first_arg_offset
+=
1
;
}
// The `noalias` attribute on the return value is useful to a
...
...
@@ -695,6 +706,30 @@ pub fn trans_call_inner<'a>(
_
=>
{}
}
debug!
(
"trans_callee_inner: first_arg_offset={}"
,
first_arg_offset
);
for
(
idx
,
&
t
)
in
ty
::
ty_fn_args
(
callee_ty
)
.iter
()
.enumerate
()
.map
(|(
i
,
v
)|
(
i
+
first_arg_offset
,
v
))
{
use
middle
::
ty
::{
BrAnon
,
ReLateBound
};
if
!
type_is_immediate
(
ccx
,
t
)
{
// if it's not immediate, we have a program-invisible pointer,
// which it can't possibly capture
attrs
.push
((
idx
,
NoCaptureAttribute
));
debug!
(
"trans_callee_inner: argument {} nocapture because it's non-immediate"
,
idx
);
continue
;
}
let
t_
=
ty
::
get
(
t
);
match
t_
.sty
{
ty
::
ty_rptr
(
ReLateBound
(
_
,
BrAnon
(
_
)),
_
)
=>
{
debug!
(
"trans_callee_inner: argument {} nocapture because
\
of anonymous lifetime"
,
idx
);
attrs
.push
((
idx
,
NoCaptureAttribute
));
},
_
=>
{
}
}
}
// Invoke the actual rust fn and update bcx/llresult.
let
(
llret
,
b
)
=
base
::
invoke
(
bcx
,
llfn
,
...
...
src/test/run-pass/out-of-stack.rs
浏览文件 @
25e52383
...
...
@@ -28,6 +28,7 @@ fn silent_recurse() {
fn
loud_recurse
()
{
println!
(
"hello!"
);
loud_recurse
();
black_box
(());
// don't optimize this into a tail call. please.
}
fn
main
()
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录