diff options
| author | bors <bors@rust-lang.org> | 2013-10-17 23:16:22 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-10-17 23:16:22 -0700 |
| commit | d0d554456a9c641c873f34c3f03a8679065d0f07 (patch) | |
| tree | c581d0a03532d0f0955770b0fd8903c05197f1ec /src/libsyntax | |
| parent | 0e4d1fc8cae42e15e00f71d9f439b01bb25a86ae (diff) | |
| parent | 7ab0b0cd41fc4bf567694ebedb2d927da9bf2551 (diff) | |
| download | rust-d0d554456a9c641c873f34c3f03a8679065d0f07.tar.gz rust-d0d554456a9c641c873f34c3f03a8679065d0f07.zip | |
auto merge of #9850 : eddyb/rust/inline-asm-constraints, r=luqmana
I've implemented analysis support for the [GCC '=' write-only inline asm constraint modifier](http://gcc.gnu.org/onlinedocs/gcc/Modifiers.html). I had more changes, for '+' (read+write) as well, but it turns out LLVM doesn't support '+' at all.
I've removed the need for wrapping each output in ExprAddrOf, as that would require unwrapping almost everywhere and it was harder to reason about in borrowck than ExprAssign's LHS.
With this change, rustc will treat (in respect to validity of accessing a local) code like this:
```rust
let x: int;
unsafe {
asm!("mov $1, $0" : "=r"(x) : "r"(5u));
}
```
as if it were this:
```rust
let x : int;
x = 5;
```
Previously, the local was required to be both mutable and initialized, and the write effect wasn't recorded.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ext/asm.rs | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/src/libsyntax/ext/asm.rs b/src/libsyntax/ext/asm.rs index e836367555a..f4b1c7f1f06 100644 --- a/src/libsyntax/ext/asm.rs +++ b/src/libsyntax/ext/asm.rs @@ -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); |
