about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-10-17 23:16:22 -0700
committerbors <bors@rust-lang.org>2013-10-17 23:16:22 -0700
commitd0d554456a9c641c873f34c3f03a8679065d0f07 (patch)
treec581d0a03532d0f0955770b0fd8903c05197f1ec /src/libsyntax
parent0e4d1fc8cae42e15e00f71d9f439b01bb25a86ae (diff)
parent7ab0b0cd41fc4bf567694ebedb2d927da9bf2551 (diff)
downloadrust-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.rs21
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);