-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Handle GCC's write-only inline asm constraint in liveness, borrowck and trans. #9850
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// 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() {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// 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` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All of these tests will probably only work on x86 and x64 architectures. I don't think that we have a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel like it might work since arm does have a mov instruction and there doesn't seem to be any x86 specific stuff. But yea, for anything more complicated definitely using target_arch is the way to go. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The best way to do this IMO is to have another function that main calls that has the per-arch tests in it. That way if we port to a new arch, this test won't silently do nothing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While grepping for |
||
} | ||
foo(x); | ||
} | ||
|
||
#[cfg(not(target_arch = "x86"), not(target_arch = "x86_64"))] | ||
pub fn main() {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// 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() {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// 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() {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// 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() {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not entirely sure about this, but
ExprAssign
at least calls this after the outputs have been handled. Could you add a few test cases with colorful usage of inputs and outputs to make sure that this tracks them correctly? One case off the top of my head that I can think of is a simultaneous use and assignment of an uninitialized variable should be disallowed.