Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
7ab0b0cd
R
Rust
项目概览
int
/
Rust
12 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
7ab0b0cd
编写于
10月 17, 2013
作者:
E
Eduard Burtescu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Handle inline asm outputs as write-only in liveness, borrowck and trans.
上级
737413d7
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
193 addition
and
50 deletion
+193
-50
src/librustc/middle/borrowck/check_loans.rs
src/librustc/middle/borrowck/check_loans.rs
+6
-1
src/librustc/middle/borrowck/gather_loans/mod.rs
src/librustc/middle/borrowck/gather_loans/mod.rs
+18
-1
src/librustc/middle/liveness.rs
src/librustc/middle/liveness.rs
+7
-9
src/librustc/middle/trans/asm.rs
src/librustc/middle/trans/asm.rs
+14
-33
src/libsyntax/ext/asm.rs
src/libsyntax/ext/asm.rs
+15
-6
src/test/compile-fail/asm-in-bad-modifier.rs
src/test/compile-fail/asm-in-bad-modifier.rs
+27
-0
src/test/compile-fail/asm-out-assign-imm.rs
src/test/compile-fail/asm-out-assign-imm.rs
+26
-0
src/test/compile-fail/asm-out-no-modifier.rs
src/test/compile-fail/asm-out-no-modifier.rs
+24
-0
src/test/compile-fail/asm-out-read-uninit.rs
src/test/compile-fail/asm-out-read-uninit.rs
+24
-0
src/test/run-pass/asm-out-assign.rs
src/test/run-pass/asm-out-assign.rs
+32
-0
未找到文件。
src/librustc/middle/borrowck/check_loans.rs
浏览文件 @
7ab0b0cd
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// Copyright 2012
-2013
The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
...
...
@@ -839,6 +839,11 @@ fn check_loans_in_expr<'a>(this: &mut CheckLoanCtxt<'a>,
expr
.span
,
[]);
}
ast
::
ExprInlineAsm
(
ref
ia
)
=>
{
for
&
(
_
,
out
)
in
ia
.outputs
.iter
()
{
this
.check_assignment
(
out
);
}
}
_
=>
{
}
}
}
...
...
src/librustc/middle/borrowck/gather_loans/mod.rs
浏览文件 @
7ab0b0cd
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// Copyright 2012
-2013
The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
...
...
@@ -309,6 +309,23 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt,
visit
::
walk_expr
(
this
,
ex
,
());
}
ast
::
ExprInlineAsm
(
ref
ia
)
=>
{
for
&
(
_
,
out
)
in
ia
.outputs
.iter
()
{
let
out_cmt
=
this
.bccx
.cat_expr
(
out
);
match
opt_loan_path
(
out_cmt
)
{
Some
(
out_lp
)
=>
{
gather_moves
::
gather_assignment
(
this
.bccx
,
this
.move_data
,
ex
.id
,
ex
.span
,
out_lp
,
out
.id
);
}
None
=>
{
// See the comment for ExprAssign.
}
}
}
visit
::
walk_expr
(
this
,
ex
,
());
}
_
=>
{
visit
::
walk_expr
(
this
,
ex
,
());
}
...
...
src/librustc/middle/liveness.rs
浏览文件 @
7ab0b0cd
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// Copyright 2012
-2013
The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
...
...
@@ -1227,12 +1227,15 @@ pub fn propagate_through_expr(&self, expr: @Expr, succ: LiveNode)
self
.propagate_through_expr
(
e
,
succ
)
}
ExprInlineAsm
(
ref
ia
)
=>
{
ExprInlineAsm
(
ref
ia
)
=>
{
let
succ
=
do
ia
.inputs
.rev_iter
()
.fold
(
succ
)
|
succ
,
&
(
_
,
expr
)|
{
self
.propagate_through_expr
(
expr
,
succ
)
};
do
ia
.outputs
.rev_iter
()
.fold
(
succ
)
|
succ
,
&
(
_
,
expr
)|
{
self
.propagate_through_expr
(
expr
,
succ
)
// see comment on lvalues in
// propagate_through_lvalue_components()
let
succ
=
self
.write_lvalue
(
expr
,
succ
,
ACC_WRITE
);
self
.propagate_through_lvalue_components
(
expr
,
succ
)
}
}
...
...
@@ -1478,12 +1481,7 @@ fn check_expr(this: &mut Liveness, expr: @Expr) {
// Output operands must be lvalues
for
&
(
_
,
out
)
in
ia
.outputs
.iter
()
{
match
out
.node
{
ExprAddrOf
(
_
,
inner
)
=>
{
this
.check_lvalue
(
inner
);
}
_
=>
{}
}
this
.check_lvalue
(
out
);
this
.visit_expr
(
out
,
());
}
...
...
src/librustc/middle/trans/asm.rs
浏览文件 @
7ab0b0cd
...
...
@@ -18,6 +18,8 @@
use
middle
::
trans
::
build
::
*
;
use
middle
::
trans
::
callee
;
use
middle
::
trans
::
common
::
*
;
use
middle
::
trans
::
expr
::
*
;
use
middle
::
trans
::
type_of
::
*
;
use
middle
::
ty
;
use
middle
::
trans
::
type_
::
Type
;
...
...
@@ -30,34 +32,15 @@ pub fn trans_inline_asm(bcx: @mut Block, ia: &ast::inline_asm) -> @mut Block {
let
mut
bcx
=
bcx
;
let
mut
constraints
=
~
[];
let
mut
cleanups
=
~
[];
let
mut
aoutput
s
=
~
[];
let
mut
output_type
s
=
~
[];
// Prepare the output operands
let
outputs
=
do
ia
.outputs.map
|
&
(
c
,
out
)|
{
constraints
.push
(
c
);
aoutputs
.push
(
unpack_result!
(
bcx
,
{
callee
::
trans_arg_expr
(
bcx
,
expr_ty
(
bcx
,
out
),
ty
::
ByCopy
,
out
,
&
mut
cleanups
,
callee
::
DontAutorefArg
)
}));
let
e
=
match
out
.node
{
ast
::
ExprAddrOf
(
_
,
e
)
=>
e
,
_
=>
fail2!
(
"Expression must be addr of"
)
};
unpack_result!
(
bcx
,
{
callee
::
trans_arg_expr
(
bcx
,
expr_ty
(
bcx
,
e
),
ty
::
ByCopy
,
e
,
&
mut
cleanups
,
callee
::
DontAutorefArg
)
})
let
out_datum
=
unpack_datum!
(
bcx
,
trans_to_datum
(
bcx
,
out
));
output_types
.push
(
type_of
(
bcx
.ccx
(),
out_datum
.ty
));
out_datum
.val
};
...
...
@@ -92,7 +75,7 @@ pub fn trans_inline_asm(bcx: @mut Block, ia: &ast::inline_asm) -> @mut Block {
clobbers
=
format!
(
"{},{}"
,
ia
.clobbers
,
clobbers
);
}
else
{
clobbers
.push_str
(
ia
.clobbers
);
}
;
}
// Add the clobbers to our constraints list
if
clobbers
.len
()
!=
0
&&
constraints
.len
()
!=
0
{
...
...
@@ -107,12 +90,12 @@ pub fn trans_inline_asm(bcx: @mut Block, ia: &ast::inline_asm) -> @mut Block {
let
numOutputs
=
outputs
.len
();
// Depending on how many outputs we have, the return type is different
let
output
=
if
numOutputs
==
0
{
let
output
_type
=
if
numOutputs
==
0
{
Type
::
void
()
}
else
if
numOutputs
==
1
{
val_ty
(
outputs
[
0
])
output_types
[
0
]
}
else
{
Type
::
struct_
(
output
s
.map
(|
o
|
val_ty
(
*
o
))
,
false
)
Type
::
struct_
(
output
_types
,
false
)
};
let
dialect
=
match
ia
.dialect
{
...
...
@@ -122,19 +105,17 @@ pub fn trans_inline_asm(bcx: @mut Block, ia: &ast::inline_asm) -> @mut Block {
let
r
=
do
ia
.asm.with_c_str
|
a
|
{
do
constraints
.with_c_str
|
c
|
{
InlineAsmCall
(
bcx
,
a
,
c
,
inputs
,
output
,
ia
.volatile
,
ia
.alignstack
,
dialect
)
InlineAsmCall
(
bcx
,
a
,
c
,
inputs
,
output
_type
,
ia
.volatile
,
ia
.alignstack
,
dialect
)
}
};
// Again, based on how many outputs we have
if
numOutputs
==
1
{
let
op
=
PointerCast
(
bcx
,
aoutputs
[
0
],
val_ty
(
outputs
[
0
])
.ptr_to
());
Store
(
bcx
,
r
,
op
);
Store
(
bcx
,
r
,
outputs
[
0
]);
}
else
{
for
(
i
,
o
)
in
a
outputs
.iter
()
.enumerate
()
{
for
(
i
,
o
)
in
outputs
.iter
()
.enumerate
()
{
let
v
=
ExtractValue
(
bcx
,
r
,
i
);
let
op
=
PointerCast
(
bcx
,
*
o
,
val_ty
(
outputs
[
i
])
.ptr_to
());
Store
(
bcx
,
v
,
op
);
Store
(
bcx
,
v
,
*
o
);
}
}
...
...
src/libsyntax/ext/asm.rs
浏览文件 @
7ab0b0cd
...
...
@@ -75,16 +75,18 @@ pub fn expand_asm(cx: @ExtCtxt, sp: Span, tts: &[ast::token_tree])
}
let
(
constraint
,
_
str_style
)
=
p
.parse_str
();
if
constraint
.starts_with
(
"+"
)
{
cx
.span_unimpl
(
*
p
.last_span
,
"'+' (read+write) output operand constraint modifier"
);
}
else
if
!
constraint
.starts_with
(
"="
)
{
cx
.span_err
(
*
p
.last_span
,
"output operand constraint lacks '='"
);
}
p
.expect
(
&
token
::
LPAREN
);
let
out
=
p
.parse_expr
();
p
.expect
(
&
token
::
RPAREN
);
let
out
=
@
ast
::
Expr
{
id
:
ast
::
DUMMY_NODE_ID
,
span
:
out
.span
,
node
:
ast
::
ExprAddrOf
(
ast
::
MutMutable
,
out
)
};
outputs
.push
((
constraint
,
out
));
}
}
...
...
@@ -98,6 +100,13 @@ pub fn expand_asm(cx: @ExtCtxt, sp: Span, tts: &[ast::token_tree])
}
let
(
constraint
,
_
str_style
)
=
p
.parse_str
();
if
constraint
.starts_with
(
"="
)
{
cx
.span_err
(
*
p
.last_span
,
"input operand constraint contains '='"
);
}
else
if
constraint
.starts_with
(
"+"
)
{
cx
.span_err
(
*
p
.last_span
,
"input operand constraint contains '+'"
);
}
p
.expect
(
&
token
::
LPAREN
);
let
input
=
p
.parse_expr
();
p
.expect
(
&
token
::
RPAREN
);
...
...
src/test/compile-fail/asm-in-bad-modifier.rs
0 → 100644
浏览文件 @
7ab0b0cd
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn
foo
(
x
:
int
)
{
info2!
(
"{}"
,
x
);
}
#[cfg(target_arch
=
"x86"
)]
#[cfg(target_arch
=
"x86_64"
)]
pub
fn
main
()
{
let
x
:
int
;
let
y
:
int
;
unsafe
{
asm!
(
"mov $1, $0"
:
"=r"
(
x
)
:
"=r"
(
5u
));
//~ ERROR input operand constraint contains '='
asm!
(
"mov $1, $0"
:
"=r"
(
y
)
:
"+r"
(
5u
));
//~ ERROR input operand constraint contains '+'
}
foo
(
x
);
foo
(
y
);
}
#[cfg(not(target_arch
=
"x86"
),
not(target_arch
=
"x86_64"
))]
pub
fn
main
()
{}
src/test/compile-fail/asm-out-assign-imm.rs
0 → 100644
浏览文件 @
7ab0b0cd
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn
foo
(
x
:
int
)
{
info2!
(
"{}"
,
x
);
}
#[cfg(target_arch
=
"x86"
)]
#[cfg(target_arch
=
"x86_64"
)]
pub
fn
main
()
{
let
x
:
int
;
x
=
1
;
//~ NOTE prior assignment occurs here
foo
(
x
);
unsafe
{
asm!
(
"mov $1, $0"
:
"=r"
(
x
)
:
"r"
(
5u
));
//~ ERROR re-assignment of immutable variable `x`
}
foo
(
x
);
}
#[cfg(not(target_arch
=
"x86"
),
not(target_arch
=
"x86_64"
))]
pub
fn
main
()
{}
src/test/compile-fail/asm-out-no-modifier.rs
0 → 100644
浏览文件 @
7ab0b0cd
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn
foo
(
x
:
int
)
{
info2!
(
"{}"
,
x
);
}
#[cfg(target_arch
=
"x86"
)]
#[cfg(target_arch
=
"x86_64"
)]
pub
fn
main
()
{
let
x
:
int
;
unsafe
{
asm!
(
"mov $1, $0"
:
"r"
(
x
)
:
"r"
(
5u
));
//~ ERROR output operand constraint lacks '='
}
foo
(
x
);
}
#[cfg(not(target_arch
=
"x86"
),
not(target_arch
=
"x86_64"
))]
pub
fn
main
()
{}
src/test/compile-fail/asm-out-read-uninit.rs
0 → 100644
浏览文件 @
7ab0b0cd
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn
foo
(
x
:
int
)
{
info2!
(
"{}"
,
x
);
}
#[cfg(target_arch
=
"x86"
)]
#[cfg(target_arch
=
"x86_64"
)]
pub
fn
main
()
{
let
x
:
int
;
unsafe
{
asm!
(
"mov $1, $0"
:
"=r"
(
x
)
:
"r"
(
x
));
//~ ERROR use of possibly uninitialized value: `x`
}
foo
(
x
);
}
#[cfg(not(target_arch
=
"x86"
),
not(target_arch
=
"x86_64"
))]
pub
fn
main
()
{}
src/test/run-pass/asm-out-assign.rs
0 → 100644
浏览文件 @
7ab0b0cd
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[cfg(target_arch
=
"x86"
)]
#[cfg(target_arch
=
"x86_64"
)]
pub
fn
main
()
{
let
x
:
int
;
unsafe
{
// Treat the output as initialization.
asm!
(
"mov $1, $0"
:
"=r"
(
x
)
:
"r"
(
5u
));
}
assert_eq!
(
x
,
5
);
let
mut
x
=
x
+
1
;
assert_eq!
(
x
,
6
);
unsafe
{
// Assignment to mutable.
asm!
(
"mov $1, $0"
:
"=r"
(
x
)
:
"r"
(
x
+
7
));
}
assert_eq!
(
x
,
13
);
}
#[cfg(not(target_arch
=
"x86"
),
not(target_arch
=
"x86_64"
))]
pub
fn
main
()
{}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录