Auto merge of #84107 - Amanieu:global_asm2, r=nagisa

Add support for const operands and options to global_asm!

On x86, the default syntax is also switched to Intel to match asm!.

Currently `global_asm!` only supports `const` operands and the `att_syntax` option. In the future, `sym` operands will also be supported. However there is no plan to support any of the other operand types or options since they don't make sense in the context of `global_asm!`.

r? `@nagisa`
This commit is contained in:
bors 2021-05-13 22:17:43 +00:00
commit 17f30e5451
56 changed files with 1424 additions and 842 deletions

View file

@ -8,12 +8,9 @@ The tracking issue for this feature is: [#35119]
The `global_asm!` macro allows the programmer to write arbitrary
assembly outside the scope of a function body, passing it through
`rustc` and `llvm` to the assembler. The macro is a no-frills
interface to LLVM's concept of [module-level inline assembly]. That is,
all caveats applicable to LLVM's module-level inline assembly apply
to `global_asm!`.
[module-level inline assembly]: http://llvm.org/docs/LangRef.html#module-level-inline-assembly
`rustc` and `llvm` to the assembler. That is to say, `global_asm!` is
equivalent to assembling the asm with an external assembler and then
linking the resulting object file with the current crate.
`global_asm!` fills a role not currently satisfied by either `asm!`
or `#[naked]` functions. The programmer has _all_ features of the
@ -38,11 +35,11 @@ And a more complicated usage looks like this:
# mod x86 {
pub mod sally {
global_asm!(r#"
.global foo
foo:
jmp baz
"#);
global_asm!(
".global foo",
"foo:",
"jmp baz",
);
#[no_mangle]
pub unsafe extern "C" fn baz() {}
@ -56,11 +53,11 @@ extern "C" {
}
pub mod harry {
global_asm!(r#"
.global bar
bar:
jmp quux
"#);
global_asm!(
".global bar",
"bar:",
"jmp quux",
);
#[no_mangle]
pub unsafe extern "C" fn quux() {}
@ -69,8 +66,44 @@ pub mod harry {
```
You may use `global_asm!` multiple times, anywhere in your crate, in
whatever way suits you. The effect is as if you concatenated all
usages and placed the larger, single usage in the crate root.
whatever way suits you. However, you should not rely on assembler state
(e.g. assembler macros) defined in one `global_asm!` to be available in
another one. It is implementation-defined whether the multiple usages
are concatenated into one or assembled separately.
`global_asm!` also supports `const` operands like `asm!`, which allows
constants defined in Rust to be used in assembly code:
```rust,no_run
#![feature(global_asm)]
# #[cfg(any(target_arch="x86", target_arch="x86_64"))]
# mod x86 {
const C: i32 = 1234;
global_asm!(
".global bar",
"bar: .word {c}",
c = const C,
);
# }
```
The syntax for passing operands is the same as `asm!` except that only
`const` operands are allowed. Refer to the [asm](asm.md) documentation
for more details.
On x86, the assembly code will use intel syntax by default. You can
override this by adding `options(att_syntax)` at the end of the macro
arguments list:
```rust,no_run
#![feature(global_asm)]
# #[cfg(any(target_arch="x86", target_arch="x86_64"))]
# mod x86 {
global_asm!("movl ${}, %ecx", const 5, options(att_syntax));
// is equivalent to
global_asm!("mov ecx, {}", const 5);
# }
```
------------------------

View file

@ -0,0 +1,14 @@
// min-llvm-version: 10.0.1
// only-x86_64
// assembly-output: emit-asm
// compile-flags: -C llvm-args=--x86-asm-syntax=intel
#![feature(asm, global_asm)]
#![crate_type = "rlib"]
// CHECK: mov eax, eax
global_asm!("mov eax, eax");
// CHECK: mov ebx, 5
global_asm!("mov ebx, {}", const 5);
// CHECK: mov ecx, 5
global_asm!("movl ${}, %ecx", const 5, options(att_syntax));

View file

@ -8,7 +8,7 @@ rust_plus_one_global_asm:
movl (%rdi), %eax
inc %eax
retq
"# );
"#, options(att_syntax));
extern {
fn cc_plus_one_c(arg : &u32) -> u32;

View file

@ -8,12 +8,19 @@
macro_rules! asm {
() => {};
}
#[rustc_builtin_macro]
macro_rules! global_asm {
() => {};
}
#[lang = "sized"]
trait Sized {}
fn main() {
unsafe {
asm!("");
//~^ ERROR asm! is unsupported on this target
//~^ ERROR inline assembly is unsupported on this target
}
}
global_asm!("");
//~^ ERROR inline assembly is unsupported on this target

View file

@ -1,8 +1,16 @@
error[E0472]: asm! is unsupported on this target
--> $DIR/bad-arch.rs:16:9
error[E0472]: inline assembly is unsupported on this target
--> $DIR/bad-arch.rs:20:9
|
LL | asm!("");
| ^^^^^^^^^
error: aborting due to previous error
error[E0472]: inline assembly is unsupported on this target
--> $DIR/bad-arch.rs:25:1
|
LL | global_asm!("");
| ^^^^^^^^^^^^^^^^
|
= note: this error originates in the macro `global_asm` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 2 previous errors

View file

@ -1,6 +1,6 @@
// only-x86_64
#![feature(asm)]
#![feature(asm, global_asm)]
fn main() {
let mut foo = 0;
@ -16,3 +16,16 @@ fn main() {
//~^ ERROR asm outputs are not allowed with the `noreturn` option
}
}
global_asm!("", options(nomem));
//~^ ERROR expected one of
global_asm!("", options(readonly));
//~^ ERROR expected one of
global_asm!("", options(noreturn));
//~^ ERROR expected one of
global_asm!("", options(pure));
//~^ ERROR expected one of
global_asm!("", options(nostack));
//~^ ERROR expected one of
global_asm!("", options(preserves_flags));
//~^ ERROR expected one of

View file

@ -28,5 +28,41 @@ error: asm outputs are not allowed with the `noreturn` option
LL | asm!("{}", out(reg) foo, options(noreturn));
| ^^^^^^^^^^^^
error: aborting due to 5 previous errors
error: expected one of `)` or `att_syntax`, found `nomem`
--> $DIR/bad-options.rs:20:25
|
LL | global_asm!("", options(nomem));
| ^^^^^ expected one of `)` or `att_syntax`
error: expected one of `)` or `att_syntax`, found `readonly`
--> $DIR/bad-options.rs:22:25
|
LL | global_asm!("", options(readonly));
| ^^^^^^^^ expected one of `)` or `att_syntax`
error: expected one of `)` or `att_syntax`, found `noreturn`
--> $DIR/bad-options.rs:24:25
|
LL | global_asm!("", options(noreturn));
| ^^^^^^^^ expected one of `)` or `att_syntax`
error: expected one of `)` or `att_syntax`, found `pure`
--> $DIR/bad-options.rs:26:25
|
LL | global_asm!("", options(pure));
| ^^^^ expected one of `)` or `att_syntax`
error: expected one of `)` or `att_syntax`, found `nostack`
--> $DIR/bad-options.rs:28:25
|
LL | global_asm!("", options(nostack));
| ^^^^^^^ expected one of `)` or `att_syntax`
error: expected one of `)` or `att_syntax`, found `preserves_flags`
--> $DIR/bad-options.rs:30:25
|
LL | global_asm!("", options(preserves_flags));
| ^^^^^^^^^^^^^^^ expected one of `)` or `att_syntax`
error: aborting due to 11 previous errors

View file

@ -1,6 +1,6 @@
// only-x86_64
#![feature(asm)]
#![feature(asm, global_asm)]
fn main() {
let mut foo = 0;
@ -26,3 +26,22 @@ fn main() {
//~^ ERROR multiple unused asm arguments
}
}
const FOO: i32 = 1;
global_asm!("{}");
//~^ ERROR invalid reference to argument at index 0
global_asm!("{1}", const FOO);
//~^ ERROR invalid reference to argument at index 1
//~^^ ERROR argument never used
global_asm!("{a}");
//~^ ERROR there is no argument named `a`
global_asm!("{}", a = const FOO);
//~^ ERROR invalid reference to argument at index 0
//~^^ ERROR argument never used
global_asm!("{1}", a = const FOO);
//~^ ERROR invalid reference to argument at index 1
//~^^ ERROR named argument never used
global_asm!("{:foo}", const FOO);
//~^ ERROR asm template modifier must be a single character
global_asm!("", const FOO, const FOO);
//~^ ERROR multiple unused asm arguments

View file

@ -98,5 +98,90 @@ LL | asm!("", in(reg) 0, in(reg) 1);
|
= help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"`
error: aborting due to 11 previous errors
error: invalid reference to argument at index 0
--> $DIR/bad-template.rs:31:14
|
LL | global_asm!("{}");
| ^^ from here
|
= note: no arguments were given
error: invalid reference to argument at index 1
--> $DIR/bad-template.rs:33:14
|
LL | global_asm!("{1}", const FOO);
| ^^^ from here
|
= note: there is 1 argument
error: argument never used
--> $DIR/bad-template.rs:33:20
|
LL | global_asm!("{1}", const FOO);
| ^^^^^^^^^ argument never used
|
= help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"`
error: there is no argument named `a`
--> $DIR/bad-template.rs:36:14
|
LL | global_asm!("{a}");
| ^^^
error: invalid reference to argument at index 0
--> $DIR/bad-template.rs:38:14
|
LL | global_asm!("{}", a = const FOO);
| ^^ ------------- named argument
| |
| from here
|
= note: no positional arguments were given
note: named arguments cannot be referenced by position
--> $DIR/bad-template.rs:38:19
|
LL | global_asm!("{}", a = const FOO);
| ^^^^^^^^^^^^^
error: named argument never used
--> $DIR/bad-template.rs:38:19
|
LL | global_asm!("{}", a = const FOO);
| ^^^^^^^^^^^^^ named argument never used
|
= help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
error: invalid reference to argument at index 1
--> $DIR/bad-template.rs:41:14
|
LL | global_asm!("{1}", a = const FOO);
| ^^^ from here
|
= note: no positional arguments were given
error: named argument never used
--> $DIR/bad-template.rs:41:20
|
LL | global_asm!("{1}", a = const FOO);
| ^^^^^^^^^^^^^ named argument never used
|
= help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
error: asm template modifier must be a single character
--> $DIR/bad-template.rs:44:16
|
LL | global_asm!("{:foo}", const FOO);
| ^^^
error: multiple unused asm arguments
--> $DIR/bad-template.rs:46:17
|
LL | global_asm!("", const FOO, const FOO);
| ^^^^^^^^^ ^^^^^^^^^ argument never used
| |
| argument never used
|
= help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"`
error: aborting due to 21 previous errors

View file

@ -2,7 +2,7 @@
// only-x86_64
// run-pass
#![feature(asm)]
#![feature(asm, global_asm)]
fn const_generic<const X: usize>() -> usize {
unsafe {
@ -34,3 +34,7 @@ fn main() {
let d = const_generic::<5>();
assert_eq!(d, 5);
}
global_asm!("mov eax, {}", const 5);
global_asm!("mov eax, {}", const constfn(5));
global_asm!("mov eax, {}", const constfn(5) + constfn(5));

View file

@ -1,7 +1,7 @@
// only-x86_64
// run-rustfix
#![feature(asm)]
#![feature(asm, global_asm)]
fn main() {
unsafe {
@ -24,3 +24,6 @@ fn main() {
);
}
}
global_asm!("", options(att_syntax, ));
//~^ ERROR the `att_syntax` option was already provided

View file

@ -1,7 +1,7 @@
// only-x86_64
// run-rustfix
#![feature(asm)]
#![feature(asm, global_asm)]
fn main() {
unsafe {
@ -24,3 +24,6 @@ fn main() {
);
}
}
global_asm!("", options(att_syntax, att_syntax));
//~^ ERROR the `att_syntax` option was already provided

View file

@ -52,5 +52,11 @@ error: the `noreturn` option was already provided
LL | options(noreturn),
| ^^^^^^^^ this option was already provided
error: aborting due to 9 previous errors
error: the `att_syntax` option was already provided
--> $DIR/duplicate-options.rs:28:37
|
LL | global_asm!("", options(att_syntax, att_syntax));
| ^^^^^^^^^^ this option was already provided
error: aborting due to 10 previous errors

View file

@ -1,5 +1,19 @@
error: unknown directive
--> $DIR/inline-syntax.rs:25:15
.intel_syntax noprefix
^
error: unknown directive
.intel_syntax noprefix
^
error: unknown directive
|
note: instantiated into assembly here
--> <inline asm>:1:1
|
LL | .intel_syntax noprefix
| ^
error: unknown directive
--> $DIR/inline-syntax.rs:29:15
|
LL | asm!(".intel_syntax noprefix", "nop");
| ^
@ -11,7 +25,7 @@ LL | .intel_syntax noprefix
| ^
error: unknown directive
--> $DIR/inline-syntax.rs:28:15
--> $DIR/inline-syntax.rs:32:15
|
LL | asm!(".intel_syntax aaa noprefix", "nop");
| ^
@ -23,7 +37,7 @@ LL | .intel_syntax aaa noprefix
| ^
error: unknown directive
--> $DIR/inline-syntax.rs:31:15
--> $DIR/inline-syntax.rs:35:15
|
LL | asm!(".att_syntax noprefix", "nop");
| ^
@ -35,7 +49,7 @@ LL | .att_syntax noprefix
| ^
error: unknown directive
--> $DIR/inline-syntax.rs:34:15
--> $DIR/inline-syntax.rs:38:15
|
LL | asm!(".att_syntax bbb noprefix", "nop");
| ^
@ -47,7 +61,7 @@ LL | .att_syntax bbb noprefix
| ^
error: unknown directive
--> $DIR/inline-syntax.rs:37:15
--> $DIR/inline-syntax.rs:41:15
|
LL | asm!(".intel_syntax noprefix; nop");
| ^
@ -59,7 +73,7 @@ LL | .intel_syntax noprefix; nop
| ^
error: unknown directive
--> $DIR/inline-syntax.rs:43:13
--> $DIR/inline-syntax.rs:47:13
|
LL | .intel_syntax noprefix
| ^
@ -70,5 +84,5 @@ note: instantiated into assembly here
LL | .intel_syntax noprefix
| ^
error: aborting due to 6 previous errors
error: aborting due to 7 previous errors

View file

@ -16,6 +16,10 @@
macro_rules! asm {
() => {};
}
#[rustc_builtin_macro]
macro_rules! global_asm {
() => {};
}
#[lang = "sized"]
trait Sized {}
@ -47,3 +51,7 @@ pub fn main() {
//[arm]~^^^^ ERROR unknown directive
}
}
global_asm!(".intel_syntax noprefix", "nop");
//[x86_64]~^ WARN avoid using `.intel_syntax`
// Assembler errors don't have line numbers, so no error on ARM

View file

@ -1,40 +1,46 @@
warning: avoid using `.intel_syntax`, Intel syntax is the default
--> $DIR/inline-syntax.rs:25:15
--> $DIR/inline-syntax.rs:55:14
|
LL | asm!(".intel_syntax noprefix", "nop");
| ^^^^^^^^^^^^^^^^^^^^^^
LL | global_asm!(".intel_syntax noprefix", "nop");
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(bad_asm_style)]` on by default
warning: avoid using `.intel_syntax`, Intel syntax is the default
--> $DIR/inline-syntax.rs:28:15
--> $DIR/inline-syntax.rs:29:15
|
LL | asm!(".intel_syntax noprefix", "nop");
| ^^^^^^^^^^^^^^^^^^^^^^
warning: avoid using `.intel_syntax`, Intel syntax is the default
--> $DIR/inline-syntax.rs:32:15
|
LL | asm!(".intel_syntax aaa noprefix", "nop");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead
--> $DIR/inline-syntax.rs:31:15
--> $DIR/inline-syntax.rs:35:15
|
LL | asm!(".att_syntax noprefix", "nop");
| ^^^^^^^^^^^^^^^^^^^^
warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead
--> $DIR/inline-syntax.rs:34:15
--> $DIR/inline-syntax.rs:38:15
|
LL | asm!(".att_syntax bbb noprefix", "nop");
| ^^^^^^^^^^^^^^^^^^^^^^^^
warning: avoid using `.intel_syntax`, Intel syntax is the default
--> $DIR/inline-syntax.rs:37:15
--> $DIR/inline-syntax.rs:41:15
|
LL | asm!(".intel_syntax noprefix; nop");
| ^^^^^^^^^^^^^^^^^^^^^^
warning: avoid using `.intel_syntax`, Intel syntax is the default
--> $DIR/inline-syntax.rs:43:13
--> $DIR/inline-syntax.rs:47:13
|
LL | .intel_syntax noprefix
| ^^^^^^^^^^^^^^^^^^^^^^
warning: 6 warnings emitted
warning: 7 warnings emitted

View file

@ -1,6 +1,6 @@
// only-x86_64
#![feature(asm)]
#![feature(asm, global_asm)]
fn main() {
let mut foo = 0;
@ -63,3 +63,37 @@ fn main() {
//~^ ERROR asm template must be a string literal
}
}
const FOO: i32 = 1;
const BAR: i32 = 2;
global_asm!();
//~^ ERROR requires at least a template string argument
global_asm!(FOO);
//~^ ERROR asm template must be a string literal
global_asm!("{}" FOO);
//~^ ERROR expected token: `,`
global_asm!("{}", FOO);
//~^ ERROR expected operand, options, or additional template string
global_asm!("{}", const);
//~^ ERROR expected expression, found end of macro arguments
global_asm!("{}", const(reg) FOO);
//~^ ERROR expected one of
global_asm!("", options(FOO));
//~^ ERROR expected one of
global_asm!("", options(nomem FOO));
//~^ ERROR expected one of
global_asm!("", options(nomem, FOO));
//~^ ERROR expected one of
global_asm!("{}", options(), const FOO);
//~^ ERROR arguments are not allowed after options
global_asm!("{a}", a = const FOO, a = const BAR);
//~^ ERROR duplicate argument named `a`
//~^^ ERROR argument never used
global_asm!("", options(), "");
//~^ ERROR expected one of
global_asm!("{}", const FOO, "{}", const FOO);
//~^ ERROR expected one of
global_asm!(format!("{{{}}}", 0), const FOO);
//~^ ERROR asm template must be a string literal
global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR);
//~^ ERROR asm template must be a string literal

View file

@ -164,6 +164,112 @@ LL | asm!("{1}", format!("{{{}}}", 0), in(reg) foo, out(reg) bar);
|
= note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
error: requires at least a template string argument
--> $DIR/parse-error.rs:69:1
|
LL | global_asm!();
| ^^^^^^^^^^^^^^
error: asm template must be a string literal
--> $DIR/parse-error.rs:71:13
|
LL | global_asm!(FOO);
| ^^^
error: expected token: `,`
--> $DIR/parse-error.rs:73:18
|
LL | global_asm!("{}" FOO);
| ^^^ expected `,`
error: expected operand, options, or additional template string
--> $DIR/parse-error.rs:75:19
|
LL | global_asm!("{}", FOO);
| ^^^ expected operand, options, or additional template string
error: expected expression, found end of macro arguments
--> $DIR/parse-error.rs:77:24
|
LL | global_asm!("{}", const);
| ^ expected expression
error: expected one of `,`, `.`, `?`, or an operator, found `FOO`
--> $DIR/parse-error.rs:79:30
|
LL | global_asm!("{}", const(reg) FOO);
| ^^^ expected one of `,`, `.`, `?`, or an operator
error: expected one of `)` or `att_syntax`, found `FOO`
--> $DIR/parse-error.rs:81:25
|
LL | global_asm!("", options(FOO));
| ^^^ expected one of `)` or `att_syntax`
error: expected one of `)` or `att_syntax`, found `nomem`
--> $DIR/parse-error.rs:83:25
|
LL | global_asm!("", options(nomem FOO));
| ^^^^^ expected one of `)` or `att_syntax`
error: expected one of `)` or `att_syntax`, found `nomem`
--> $DIR/parse-error.rs:85:25
|
LL | global_asm!("", options(nomem, FOO));
| ^^^^^ expected one of `)` or `att_syntax`
error: arguments are not allowed after options
--> $DIR/parse-error.rs:87:30
|
LL | global_asm!("{}", options(), const FOO);
| --------- ^^^^^^^^^ argument
| |
| previous options
error: duplicate argument named `a`
--> $DIR/parse-error.rs:89:35
|
LL | global_asm!("{a}", a = const FOO, a = const BAR);
| ------------- ^^^^^^^^^^^^^ duplicate argument
| |
| previously here
error: argument never used
--> $DIR/parse-error.rs:89:35
|
LL | global_asm!("{a}", a = const FOO, a = const BAR);
| ^^^^^^^^^^^^^ argument never used
|
= help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"`
error: expected one of `const` or `options`, found `""`
--> $DIR/parse-error.rs:92:28
|
LL | global_asm!("", options(), "");
| ^^ expected one of `const` or `options`
error: expected one of `const` or `options`, found `"{}"`
--> $DIR/parse-error.rs:94:30
|
LL | global_asm!("{}", const FOO, "{}", const FOO);
| ^^^^ expected one of `const` or `options`
error: asm template must be a string literal
--> $DIR/parse-error.rs:96:13
|
LL | global_asm!(format!("{{{}}}", 0), const FOO);
| ^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
error: asm template must be a string literal
--> $DIR/parse-error.rs:98:20
|
LL | global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR);
| ^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/parse-error.rs:37:37
|
@ -218,6 +324,6 @@ LL | let mut bar = 0;
LL | asm!("{1}", in("eax") foo, const bar);
| ^^^ non-constant value
error: aborting due to 31 previous errors
error: aborting due to 47 previous errors
For more information about this error, try `rustc --explain E0435`.

View file

@ -1,6 +1,6 @@
// only-x86_64
#![feature(asm, repr_simd, never_type)]
#![feature(asm, global_asm, repr_simd, never_type)]
#[repr(simd)]
struct SimdNonCopy(f32, f32, f32, f32);
@ -90,3 +90,11 @@ fn main() {
asm!("{}", in(reg) u);
}
}
// Const operands must be integer or floats, and must be constants.
global_asm!("{}", const 0);
global_asm!("{}", const 0i32);
global_asm!("{}", const 0f32);
global_asm!("{}", const 0 as *mut u8);
//~^ ERROR asm `const` arguments must be integer or floating-point values

View file

@ -61,6 +61,12 @@ LL | asm!("{}", inout(reg) r);
|
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
error: asm `const` arguments must be integer or floating-point values
--> $DIR/type-check-2.rs:99:19
|
LL | global_asm!("{}", const 0 as *mut u8);
| ^^^^^^^^^^^^^^^^^^
error: asm `sym` operand must point to a fn or static
--> $DIR/type-check-2.rs:47:24
|
@ -103,7 +109,7 @@ LL | let v: Vec<u64> = vec![0, 1, 2];
LL | asm!("{}", inout(reg) v[0]);
| ^ cannot borrow as mutable
error: aborting due to 14 previous errors
error: aborting due to 15 previous errors
Some errors have detailed explanations: E0381, E0596.
For more information about an error, try `rustc --explain E0381`.

View file

@ -1,7 +1,7 @@
// only-x86_64
// compile-flags: -C target-feature=+avx512f
#![feature(asm)]
#![feature(asm, global_asm)]
use std::arch::x86_64::{_mm256_setzero_ps, _mm_setzero_ps};
@ -69,3 +69,21 @@ fn main() {
asm!("{:r}", inout(reg) main => val_u64);
}
}
// Constants must be... constant
static S: i32 = 1;
const fn const_foo(x: i32) -> i32 {
x
}
const fn const_bar<T>(x: T) -> T {
x
}
global_asm!("{}", const S);
//~^ ERROR constants cannot refer to statics
global_asm!("{}", const const_foo(0));
global_asm!("{}", const const_foo(S));
//~^ ERROR constants cannot refer to statics
global_asm!("{}", const const_bar(0));
global_asm!("{}", const const_bar(S));
//~^ ERROR constants cannot refer to statics

View file

@ -114,5 +114,30 @@ LL | asm!("{:r}", inout(reg) main => val_u32);
|
= note: asm inout arguments must have the same type, unless they are both pointers or integers of the same size
error: aborting due to 9 previous errors; 4 warnings emitted
error[E0013]: constants cannot refer to statics
--> $DIR/type-check-3.rs:82:25
|
LL | global_asm!("{}", const S);
| ^
|
= help: consider extracting the value of the `static` to a `const`, and referring to that
error[E0013]: constants cannot refer to statics
--> $DIR/type-check-3.rs:85:35
|
LL | global_asm!("{}", const const_foo(S));
| ^
|
= help: consider extracting the value of the `static` to a `const`, and referring to that
error[E0013]: constants cannot refer to statics
--> $DIR/type-check-3.rs:88:35
|
LL | global_asm!("{}", const const_bar(S));
| ^
|
= help: consider extracting the value of the `static` to a `const`, and referring to that
error: aborting due to 12 previous errors; 4 warnings emitted
For more information about this error, try `rustc --explain E0013`.

View file

@ -1,7 +1,7 @@
#![feature(global_asm)]
fn main() {
global_asm!(); //~ ERROR requires a string literal as an argument
global_asm!(); //~ ERROR requires at least a template string argument
global_asm!(struct); //~ ERROR expected expression
global_asm!(123); //~ ERROR inline assembly must be a string literal
global_asm!(123); //~ ERROR asm template must be a string literal
}

View file

@ -1,8 +1,8 @@
error: macro requires a string literal as an argument
error: requires at least a template string argument
--> $DIR/global-asm.rs:4:5
|
LL | global_asm!();
| ^^^^^^^^^^^^^^ string literal required
| ^^^^^^^^^^^^^^
error: expected expression, found keyword `struct`
--> $DIR/global-asm.rs:5:17
@ -10,7 +10,7 @@ error: expected expression, found keyword `struct`
LL | global_asm!(struct);
| ^^^^^^ expected expression
error: inline assembly must be a string literal
error: asm template must be a string literal
--> $DIR/global-asm.rs:6:17
|
LL | global_asm!(123);