Skip to content

Commit

Permalink
auto merge of #19411 : lifthrasiir/rust/asm-clobbers-expanded, r=alex…
Browse files Browse the repository at this point in the history
…crichton

I.e. we should not prematurely build operand constraints at the expansion time. Otherwise `--pretty expanded` diverges:

```
$ cat t.rs
#![feature(asm)]

pub fn main() { unsafe { asm!("" : : : "hello", "world") }; }

$ rustc t.rs --pretty
#![feature(asm)]

pub fn main() { unsafe { asm!("" : : : "hello" , "world") }; }

$ rustc t.rs --pretty expanded
#![feature(asm)]
#![feature(phase)]
#![no_std]
#![feature(globs)]
#[phase(plugin, link)]
extern crate "std" as std;
#[prelude_import]
use std::prelude::*;

pub fn main() { unsafe { asm!("":  :  : "~{hello},~{world}") }; }
```

(The last code *does* compile, but won't do the expected thing.)
  • Loading branch information
bors committed Nov 30, 2014
2 parents 52888a7 + 133266f commit 3ee471c
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 22 deletions.
29 changes: 16 additions & 13 deletions src/librustc_trans/trans/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,19 +77,22 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm)
// no failure occurred preparing operands, no need to cleanup
fcx.pop_custom_cleanup_scope(temp_scope);

let mut constraints =
String::from_str(constraints.iter()
.map(|s| s.get().to_string())
.chain(ext_constraints.into_iter())
.collect::<Vec<String>>()
.connect(",")
.as_slice());

let mut clobbers = get_clobbers();
if !ia.clobbers.get().is_empty() && !clobbers.is_empty() {
clobbers = format!("{},{}", ia.clobbers.get(), clobbers);
} else {
clobbers.push_str(ia.clobbers.get());
let mut constraints = constraints.iter()
.map(|s| s.get().to_string())
.chain(ext_constraints.into_iter())
.collect::<Vec<String>>()
.connect(",");

let mut clobbers = ia.clobbers.iter()
.map(|s| format!("~{{{}}}", s.get()))
.collect::<Vec<String>>()
.connect(",");
let more_clobbers = get_clobbers();
if !more_clobbers.is_empty() {
if !clobbers.is_empty() {
clobbers.push(',');
}
clobbers.push_str(more_clobbers.as_slice());
}

// Add the clobbers to our constraints list
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1177,7 +1177,7 @@ pub struct InlineAsm {
pub asm_str_style: StrStyle,
pub outputs: Vec<(InternedString, P<Expr>, bool)>,
pub inputs: Vec<(InternedString, P<Expr>)>,
pub clobbers: InternedString,
pub clobbers: Vec<InternedString>,
pub volatile: bool,
pub alignstack: bool,
pub dialect: AsmDialect,
Expand Down
10 changes: 3 additions & 7 deletions src/libsyntax/ext/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
let mut asm_str_style = None;
let mut outputs = Vec::new();
let mut inputs = Vec::new();
let mut cons = "".to_string();
let mut clobs = Vec::new();
let mut volatile = false;
let mut alignstack = false;
let mut dialect = ast::AsmAtt;
Expand Down Expand Up @@ -138,7 +138,6 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
}
}
Clobbers => {
let mut clobs = Vec::new();
while p.token != token::Eof &&
p.token != token::Colon &&
p.token != token::ModSep {
Expand All @@ -148,15 +147,12 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
}

let (s, _str_style) = p.parse_str();
let clob = format!("~{{{}}}", s);
clobs.push(clob);

if OPTIONS.iter().any(|opt| s.equiv(opt)) {
cx.span_warn(p.last_span, "expected a clobber, found an option");
}
clobs.push(s);
}

cons = clobs.connect(",");
}
Options => {
let (option, _str_style) = p.parse_str();
Expand Down Expand Up @@ -216,7 +212,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
asm_str_style: asm_str_style.unwrap(),
outputs: outputs,
inputs: inputs,
clobbers: token::intern_and_get_ident(cons.as_slice()),
clobbers: clobs,
volatile: volatile,
alignstack: alignstack,
dialect: dialect,
Expand Down
6 changes: 5 additions & 1 deletion src/libsyntax/print/pprust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1839,7 +1839,11 @@ impl<'a> State<'a> {
try!(space(&mut self.s));
try!(self.word_space(":"));

try!(self.print_string(a.clobbers.get(), ast::CookedStr));
try!(self.commasep(Inconsistent, a.clobbers.as_slice(),
|s, co| {
try!(s.print_string(co.get(), ast::CookedStr));
Ok(())
}));
try!(self.pclose());
}
ast::ExprMac(ref m) => try!(self.print_mac(m)),
Expand Down
14 changes: 14 additions & 0 deletions src/test/pretty/asm-clobbers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright 2014 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.

#![feature(asm)]

pub fn main() { unsafe { asm!("" : : : "hello", "world") }; }

0 comments on commit 3ee471c

Please sign in to comment.