diff options
| author | Folkert de Vries <folkert@folkertdev.nl> | 2025-04-30 11:23:09 +0200 |
|---|---|---|
| committer | Folkert de Vries <folkert@folkertdev.nl> | 2025-05-27 09:44:04 +0200 |
| commit | e3bbbeeafd159b9cb7b000950420a20d8910fd5e (patch) | |
| tree | 89532d311a99463ff3f7c0ff20d14a088f22b134 /tests/ui/asm | |
| parent | 6eef33bb399cabfab16aa4e0825895f5f32f4e26 (diff) | |
| download | rust-e3bbbeeafd159b9cb7b000950420a20d8910fd5e.tar.gz rust-e3bbbeeafd159b9cb7b000950420a20d8910fd5e.zip | |
support `#[cfg(...)]` on arguments to the `asm!` macros
Diffstat (limited to 'tests/ui/asm')
| -rw-r--r-- | tests/ui/asm/cfg-parse-error.rs | 56 | ||||
| -rw-r--r-- | tests/ui/asm/cfg-parse-error.stderr | 36 | ||||
| -rw-r--r-- | tests/ui/asm/cfg.rs | 125 |
3 files changed, 217 insertions, 0 deletions
diff --git a/tests/ui/asm/cfg-parse-error.rs b/tests/ui/asm/cfg-parse-error.rs new file mode 100644 index 00000000000..c66a627ca94 --- /dev/null +++ b/tests/ui/asm/cfg-parse-error.rs @@ -0,0 +1,56 @@ +//@ needs-asm-support +#![feature(asm_cfg)] + +use std::arch::asm; + +fn main() { + unsafe { + asm!( + "", + #[cfg(false)] + clobber_abi("C"), + #[cfg(false)] + options(att_syntax), + #[cfg(false)] + a = out(reg) x, + "", + //~^ ERROR expected one of `clobber_abi`, `const` + ); + asm!( + #[cfg(false)] + "", + #[cfg(false)] + const { + 5 + }, + "", //~ ERROR expected one of `clobber_abi`, `const` + ); + + asm!( + #[cfg_attr(true, cfg(false))] + const { + 5 + }, + "", + ); + + // This is not accepted because `a = out(reg) x` is not a valid expression. + asm!( + #[cfg(false)] + a = out(reg) x, //~ ERROR expected token: `,` + "", + ); + + // For now, any non-cfg attributes are rejected + asm!( + #[rustfmt::skip] //~ ERROR this attribute is not supported on assembly + "", + ); + + // For now, any non-cfg attributes are rejected + asm!( + #![rustfmt::skip] //~ ERROR an inner attribute is not permitted in this context + "", + ); + } +} diff --git a/tests/ui/asm/cfg-parse-error.stderr b/tests/ui/asm/cfg-parse-error.stderr new file mode 100644 index 00000000000..19c76adee63 --- /dev/null +++ b/tests/ui/asm/cfg-parse-error.stderr @@ -0,0 +1,36 @@ +error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `label`, `lateout`, `options`, `out`, or `sym`, found `""` + --> $DIR/cfg-parse-error.rs:16:13 + | +LL | a = out(reg) x, + | - expected one of 10 possible tokens +LL | "", + | ^^ unexpected token + +error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `label`, `lateout`, `options`, `out`, or `sym`, found `""` + --> $DIR/cfg-parse-error.rs:26:13 + | +LL | }, + | - expected one of 10 possible tokens +LL | "", + | ^^ unexpected token + +error: expected token: `,` + --> $DIR/cfg-parse-error.rs:40:26 + | +LL | a = out(reg) x, + | ^ expected `,` + +error: this attribute is not supported on assembly + --> $DIR/cfg-parse-error.rs:46:13 + | +LL | #[rustfmt::skip] + | ^^^^^^^^^^^^^^^^ + +error: this attribute is not supported on assembly + --> $DIR/cfg-parse-error.rs:52:13 + | +LL | #![rustfmt::skip] + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 5 previous errors + diff --git a/tests/ui/asm/cfg.rs b/tests/ui/asm/cfg.rs new file mode 100644 index 00000000000..bcf86340b9d --- /dev/null +++ b/tests/ui/asm/cfg.rs @@ -0,0 +1,125 @@ +// Check that `cfg` and `cfg_attr` work as expected. +// +//@ revisions: reva revb +//@ only-x86_64 +//@ run-pass +#![feature(asm_cfg, cfg_select)] + +use std::arch::{asm, naked_asm}; + +#[unsafe(naked)] +extern "C" fn ignore_const_operand() -> u64 { + naked_asm!( + "mov rax, 5", + #[cfg(revb)] + "mov rax, {a}", + "ret", + #[cfg(revb)] + a = const 10, + ) +} + +#[unsafe(naked)] +extern "C" fn ignore_const_operand_cfg_attr() -> u64 { + naked_asm!( + "mov rax, 5", + #[cfg_attr(true, cfg(revb))] + "mov rax, {a}", + "ret", + #[cfg_attr(true, cfg(revb))] + a = const 10, + ) +} + +#[unsafe(naked)] +extern "C" fn const_operand() -> u64 { + naked_asm!( + "mov rax, {a}", + "ret", + #[cfg(reva)] + a = const 5, + #[cfg(revb)] + a = const 10, + ) +} + +fn options() { + // Without the cfg, this throws an error that the `att_syntax` option is provided twice. + unsafe { + asm!( + "nop", + #[cfg(false)] + options(att_syntax), + options(att_syntax) + ) + } +} + +fn clobber_abi() { + // Without the cfg, this throws an error that the "C" abi is provided twice. + unsafe { + asm!( + "nop", + #[cfg(false)] + clobber_abi("C"), + clobber_abi("C"), + ); + } +} + +#[unsafe(naked)] +extern "C" fn first_template() -> u64 { + naked_asm!( + #[cfg(reva)] + "mov rax, 5", + #[cfg(revb)] + "mov rax, 10", + "ret", + ) +} + +#[unsafe(naked)] +extern "C" fn true_and_false() -> u64 { + naked_asm!( + "mov rax, 5", + #[cfg(true)] + #[cfg(false)] + "mov rax, 10", + "ret", + ) +} + +#[unsafe(naked)] +extern "C" fn false_and_true() -> u64 { + naked_asm!( + "mov rax, 5", + #[cfg(false)] + #[cfg(true)] + "mov rax, 10", + "ret", + ) +} + +pub fn main() { + std::cfg_select! { + reva => { + assert_eq!(const_operand(), 5); + assert_eq!(ignore_const_operand_cfg_attr(), 5); + assert_eq!(ignore_const_operand(), 5); + assert_eq!(first_template(), 5); + + } + revb => { + assert_eq!(const_operand(), 10); + assert_eq!(ignore_const_operand_cfg_attr(), 10); + assert_eq!(ignore_const_operand(), 10); + assert_eq!(first_template(), 10); + + } + } + options(); + clobber_abi(); + + assert_eq!(true_and_false(), 5); + assert_eq!(false_and_true(), 5); +} |
