Skip to content

Commit 0405aa0

Browse files
authored
Merge pull request rust-lang#163 from yvt/fix-asm-sym
Add inline assembly `sym` operands as GCC input operands
2 parents 248c1c5 + 63ffdfd commit 0405aa0

File tree

6 files changed

+68
-9
lines changed

6 files changed

+68
-9
lines changed

Cargo.toml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,12 @@ license = "MIT OR Apache-2.0"
99
crate-type = ["dylib"]
1010

1111
[[test]]
12-
name = "lang_tests"
13-
path = "tests/lib.rs"
12+
name = "lang_tests_debug"
13+
path = "tests/lang_tests_debug.rs"
14+
harness = false
15+
[[test]]
16+
name = "lang_tests_release"
17+
path = "tests/lang_tests_release.rs"
1418
harness = false
1519

1620
[features]

src/asm.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use std::borrow::Cow;
1313
use crate::builder::Builder;
1414
use crate::context::CodegenCx;
1515
use crate::type_of::LayoutGccExt;
16+
use crate::callee::get_fn;
1617

1718

1819
// Rust asm! and GCC Extended Asm semantics differ substantially.
@@ -342,9 +343,24 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
342343
// processed in the previous pass
343344
}
344345

345-
InlineAsmOperandRef::Const { .. }
346-
| InlineAsmOperandRef::SymFn { .. }
347-
| InlineAsmOperandRef::SymStatic { .. } => {
346+
InlineAsmOperandRef::SymFn { instance } => {
347+
inputs.push(AsmInOperand {
348+
constraint: "X".into(),
349+
rust_idx,
350+
val: self.cx.rvalue_as_function(get_fn(self.cx, instance))
351+
.get_address(None),
352+
});
353+
}
354+
355+
InlineAsmOperandRef::SymStatic { def_id } => {
356+
inputs.push(AsmInOperand {
357+
constraint: "X".into(),
358+
rust_idx,
359+
val: self.cx.get_static(def_id).get_address(None),
360+
});
361+
}
362+
363+
InlineAsmOperandRef::Const { .. } => {
348364
// processed in the previous pass
349365
}
350366
}

tests/lib.rs renamed to tests/lang_tests_common.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//! The common code for `tests/lang_tests_*.rs`
12
use std::{
23
env::{self, current_dir},
34
path::PathBuf,
@@ -7,7 +8,15 @@ use std::{
78
use lang_tester::LangTester;
89
use tempfile::TempDir;
910

10-
fn main() {
11+
/// Controls the compile options (e.g., optimization level) used to compile
12+
/// test code.
13+
#[allow(dead_code)] // Each test crate picks one variant
14+
pub enum Profile {
15+
Debug,
16+
Release,
17+
}
18+
19+
pub fn main_inner(profile: Profile) {
1120
let tempdir = TempDir::new().expect("temp dir");
1221
let current_dir = current_dir().expect("current dir");
1322
let current_dir = current_dir.to_str().expect("current dir").to_string();
@@ -42,6 +51,15 @@ fn main() {
4251
"-o", exe.to_str().expect("to_str"),
4352
path.to_str().expect("to_str"),
4453
]);
54+
match profile {
55+
Profile::Debug => {}
56+
Profile::Release => {
57+
compiler.args(&[
58+
"-C", "opt-level=3",
59+
"-C", "lto=no",
60+
]);
61+
}
62+
}
4563
// Test command 2: run `tempdir/x`.
4664
let runtime = Command::new(exe);
4765
vec![("Compiler", compiler), ("Run-time", runtime)]

tests/lang_tests_debug.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
mod lang_tests_common;
2+
3+
fn main() {
4+
lang_tests_common::main_inner(lang_tests_common::Profile::Debug);
5+
}

tests/lang_tests_release.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
mod lang_tests_common;
2+
3+
fn main() {
4+
lang_tests_common::main_inner(lang_tests_common::Profile::Release);
5+
}

tests/run/int_overflow.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Compiler:
22
//
33
// Run-time:
4-
// stdout: Panicking
4+
// stdout: Success
55
// status: signal
66

77
#![allow(unused_attributes)]
@@ -64,7 +64,9 @@ mod intrinsics {
6464
#[no_mangle]
6565
pub fn panic(_msg: &str) -> ! {
6666
unsafe {
67-
libc::puts("Panicking\0" as *const str as *const u8);
67+
// Panicking is expected iff overflow checking is enabled.
68+
#[cfg(debug_assertions)]
69+
libc::puts("Success\0" as *const str as *const u8);
6870
libc::fflush(libc::stdout);
6971
intrinsics::abort();
7072
}
@@ -124,6 +126,15 @@ impl Add for isize {
124126
#[start]
125127
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
126128
let int = 9223372036854775807isize;
127-
let int = int + argc;
129+
let int = int + argc; // overflow
130+
131+
// If overflow checking is disabled, we should reach here.
132+
#[cfg(not(debug_assertions))]
133+
unsafe {
134+
libc::puts("Success\0" as *const str as *const u8);
135+
libc::fflush(libc::stdout);
136+
intrinsics::abort();
137+
}
138+
128139
int
129140
}

0 commit comments

Comments
 (0)