diff options
| author | bors <bors@rust-lang.org> | 2021-06-25 20:44:28 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-06-25 20:44:28 +0000 |
| commit | e6b4c252ea33e9f80ab8b8d7b3f6393e54166127 (patch) | |
| tree | bb654e936af73f4066d67249db441e4315d8363b | |
| parent | 0d7f236b8a255b7e0afa19223bfe72cbaf9cc2d5 (diff) | |
| parent | d0443bb7c2c42d03e7a329e2e18eef779bd2e0e9 (diff) | |
| download | rust-e6b4c252ea33e9f80ab8b8d7b3f6393e54166127.tar.gz rust-e6b4c252ea33e9f80ab8b8d7b3f6393e54166127.zip | |
Auto merge of #86599 - Amanieu:asm_raw, r=nagisa
Add a "raw" option for asm! which ignores format string specifiers This is useful when including raw assembly snippets using `include_str!`.
| -rw-r--r-- | compiler/rustc_ast/src/ast.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_ast_pretty/src/pprust/state.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/asm.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_hir_pretty/src/lib.rs | 3 | ||||
| -rw-r--r-- | src/doc/unstable-book/src/library-features/asm.md | 3 | ||||
| -rw-r--r-- | src/test/codegen/asm-options.rs | 7 | ||||
| -rw-r--r-- | src/test/ui/asm/bad-options.stderr | 24 | ||||
| -rw-r--r-- | src/test/ui/asm/parse-error.stderr | 20 |
8 files changed, 48 insertions, 23 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index d3f5a37fd6e..03282fd5164 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1935,6 +1935,7 @@ bitflags::bitflags! { const NORETURN = 1 << 4; const NOSTACK = 1 << 5; const ATT_SYNTAX = 1 << 6; + const RAW = 1 << 7; } } diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 3d2785faad6..ffee5cdc331 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -2284,6 +2284,9 @@ impl<'a> State<'a> { if opts.contains(InlineAsmOptions::ATT_SYNTAX) { options.push("att_syntax"); } + if opts.contains(InlineAsmOptions::RAW) { + options.push("raw"); + } s.commasep(Inconsistent, &options, |s, &opt| { s.word(opt); }); diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index b28c6f0d99c..97e07d52cc3 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -356,6 +356,8 @@ fn parse_options<'a>( try_set_option(p, args, sym::nostack, ast::InlineAsmOptions::NOSTACK); } else if p.eat_keyword(sym::att_syntax) { try_set_option(p, args, sym::att_syntax, ast::InlineAsmOptions::ATT_SYNTAX); + } else if p.eat_keyword(kw::Raw) { + try_set_option(p, args, kw::Raw, ast::InlineAsmOptions::RAW); } else { return p.unexpected(); } @@ -467,6 +469,14 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl } } + // Don't treat raw asm as a format string. + if args.options.contains(ast::InlineAsmOptions::RAW) { + template.push(ast::InlineAsmTemplatePiece::String(template_str.to_string())); + let template_num_lines = 1 + template_str.matches('\n').count(); + line_spans.extend(std::iter::repeat(template_sp).take(template_num_lines)); + continue; + } + let mut parser = parse::Parser::new( template_str, str_style, diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index d11dca1cba4..3211c7c5621 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1444,6 +1444,9 @@ impl<'a> State<'a> { if opts.contains(ast::InlineAsmOptions::ATT_SYNTAX) { options.push("att_syntax"); } + if opts.contains(ast::InlineAsmOptions::RAW) { + options.push("raw"); + } s.commasep(Inconsistent, &options, |s, &opt| { s.word(opt); }); diff --git a/src/doc/unstable-book/src/library-features/asm.md b/src/doc/unstable-book/src/library-features/asm.md index 03dbf4fb617..2cf6801ad1c 100644 --- a/src/doc/unstable-book/src/library-features/asm.md +++ b/src/doc/unstable-book/src/library-features/asm.md @@ -456,7 +456,7 @@ reg_spec := <register class> / "<explicit register>" operand_expr := expr / "_" / expr "=>" expr / expr "=>" "_" reg_operand := dir_spec "(" reg_spec ")" operand_expr operand := reg_operand / "const" const_expr / "sym" path -option := "pure" / "nomem" / "readonly" / "preserves_flags" / "noreturn" / "nostack" / "att_syntax" +option := "pure" / "nomem" / "readonly" / "preserves_flags" / "noreturn" / "nostack" / "att_syntax" / "raw" options := "options(" option *["," option] [","] ")" asm := "asm!(" format_string *("," format_string) *("," [ident "="] operand) ["," options] [","] ")" ``` @@ -781,6 +781,7 @@ Currently the following options are defined: - `noreturn`: The `asm` block never returns, and its return type is defined as `!` (never). Behavior is undefined if execution falls through past the end of the asm code. A `noreturn` asm block behaves just like a function which doesn't return; notably, local variables in scope are not dropped before it is invoked. - `nostack`: The `asm` block does not push data to the stack, or write to the stack red-zone (if supported by the target). If this option is *not* used then the stack pointer is guaranteed to be suitably aligned (according to the target ABI) for a function call. - `att_syntax`: This option is only valid on x86, and causes the assembler to use the `.att_syntax prefix` mode of the GNU assembler. Register operands are substituted in with a leading `%`. +- `raw`: This causes the template string to be parsed as a raw assembly string, with no special handling for `{` and `}`. This is primarily useful when including raw assembly code from an external file using `include_str!`. The compiler performs some additional checks on options: - The `nomem` and `readonly` options are mutually exclusive: it is a compile-time error to specify both. diff --git a/src/test/codegen/asm-options.rs b/src/test/codegen/asm-options.rs index 70391661b0c..28df0f9b852 100644 --- a/src/test/codegen/asm-options.rs +++ b/src/test/codegen/asm-options.rs @@ -94,3 +94,10 @@ pub unsafe fn dont_remove_nonpure() { asm!("", options(nomem)); asm!("", options(readonly)); } + +// CHECK-LABEL: @raw +// CHECK: call void asm sideeffect inteldialect "{} {}", ""() +#[no_mangle] +pub unsafe fn raw() { + asm!("{} {}", options(nostack, nomem, preserves_flags, raw)); +} diff --git a/src/test/ui/asm/bad-options.stderr b/src/test/ui/asm/bad-options.stderr index 4e27a6e2cb5..9039483be4b 100644 --- a/src/test/ui/asm/bad-options.stderr +++ b/src/test/ui/asm/bad-options.stderr @@ -28,41 +28,41 @@ error: asm outputs are not allowed with the `noreturn` option LL | asm!("{}", out(reg) foo, options(noreturn)); | ^^^^^^^^^^^^ -error: expected one of `)` or `att_syntax`, found `nomem` +error: expected one of `)`, `att_syntax`, or `raw`, found `nomem` --> $DIR/bad-options.rs:20:25 | LL | global_asm!("", options(nomem)); - | ^^^^^ expected one of `)` or `att_syntax` + | ^^^^^ expected one of `)`, `att_syntax`, or `raw` -error: expected one of `)` or `att_syntax`, found `readonly` +error: expected one of `)`, `att_syntax`, or `raw`, found `readonly` --> $DIR/bad-options.rs:22:25 | LL | global_asm!("", options(readonly)); - | ^^^^^^^^ expected one of `)` or `att_syntax` + | ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw` -error: expected one of `)` or `att_syntax`, found `noreturn` +error: expected one of `)`, `att_syntax`, or `raw`, found `noreturn` --> $DIR/bad-options.rs:24:25 | LL | global_asm!("", options(noreturn)); - | ^^^^^^^^ expected one of `)` or `att_syntax` + | ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw` -error: expected one of `)` or `att_syntax`, found `pure` +error: expected one of `)`, `att_syntax`, or `raw`, found `pure` --> $DIR/bad-options.rs:26:25 | LL | global_asm!("", options(pure)); - | ^^^^ expected one of `)` or `att_syntax` + | ^^^^ expected one of `)`, `att_syntax`, or `raw` -error: expected one of `)` or `att_syntax`, found `nostack` +error: expected one of `)`, `att_syntax`, or `raw`, found `nostack` --> $DIR/bad-options.rs:28:25 | LL | global_asm!("", options(nostack)); - | ^^^^^^^ expected one of `)` or `att_syntax` + | ^^^^^^^ expected one of `)`, `att_syntax`, or `raw` -error: expected one of `)` or `att_syntax`, found `preserves_flags` +error: expected one of `)`, `att_syntax`, or `raw`, found `preserves_flags` --> $DIR/bad-options.rs:30:25 | LL | global_asm!("", options(preserves_flags)); - | ^^^^^^^^^^^^^^^ expected one of `)` or `att_syntax` + | ^^^^^^^^^^^^^^^ expected one of `)`, `att_syntax`, or `raw` error: aborting due to 11 previous errors diff --git a/src/test/ui/asm/parse-error.stderr b/src/test/ui/asm/parse-error.stderr index afd262b851c..33dca61dc8e 100644 --- a/src/test/ui/asm/parse-error.stderr +++ b/src/test/ui/asm/parse-error.stderr @@ -64,11 +64,11 @@ error: argument to `sym` must be a path expression LL | asm!("{}", sym foo + bar); | ^^^^^^^^^ -error: expected one of `)`, `att_syntax`, `nomem`, `noreturn`, `nostack`, `preserves_flags`, `pure`, or `readonly`, found `foo` +error: expected one of `)`, `att_syntax`, `nomem`, `noreturn`, `nostack`, `preserves_flags`, `pure`, `raw`, or `readonly`, found `foo` --> $DIR/parse-error.rs:31:26 | LL | asm!("", options(foo)); - | ^^^ expected one of 8 possible tokens + | ^^^ expected one of 9 possible tokens error: expected one of `)` or `,`, found `foo` --> $DIR/parse-error.rs:33:32 @@ -76,11 +76,11 @@ error: expected one of `)` or `,`, found `foo` LL | asm!("", options(nomem foo)); | ^^^ expected one of `)` or `,` -error: expected one of `)`, `att_syntax`, `nomem`, `noreturn`, `nostack`, `preserves_flags`, `pure`, or `readonly`, found `foo` +error: expected one of `)`, `att_syntax`, `nomem`, `noreturn`, `nostack`, `preserves_flags`, `pure`, `raw`, or `readonly`, found `foo` --> $DIR/parse-error.rs:35:33 | LL | asm!("", options(nomem, foo)); - | ^^^ expected one of 8 possible tokens + | ^^^ expected one of 9 possible tokens error: arguments are not allowed after options --> $DIR/parse-error.rs:37:31 @@ -200,23 +200,23 @@ error: expected one of `,`, `.`, `?`, or an operator, found `FOO` LL | global_asm!("{}", const(reg) FOO); | ^^^ expected one of `,`, `.`, `?`, or an operator -error: expected one of `)` or `att_syntax`, found `FOO` +error: expected one of `)`, `att_syntax`, or `raw`, found `FOO` --> $DIR/parse-error.rs:81:25 | LL | global_asm!("", options(FOO)); - | ^^^ expected one of `)` or `att_syntax` + | ^^^ expected one of `)`, `att_syntax`, or `raw` -error: expected one of `)` or `att_syntax`, found `nomem` +error: expected one of `)`, `att_syntax`, or `raw`, found `nomem` --> $DIR/parse-error.rs:83:25 | LL | global_asm!("", options(nomem FOO)); - | ^^^^^ expected one of `)` or `att_syntax` + | ^^^^^ expected one of `)`, `att_syntax`, or `raw` -error: expected one of `)` or `att_syntax`, found `nomem` +error: expected one of `)`, `att_syntax`, or `raw`, found `nomem` --> $DIR/parse-error.rs:85:25 | LL | global_asm!("", options(nomem, FOO)); - | ^^^^^ expected one of `)` or `att_syntax` + | ^^^^^ expected one of `)`, `att_syntax`, or `raw` error: arguments are not allowed after options --> $DIR/parse-error.rs:87:30 |
