From 12c6a12d62fda3d5d070fe3915f03154ff7c80df Mon Sep 17 00:00:00 2001 From: asquared31415 <34665709+asquared31415@users.noreply.github.com> Date: Thu, 18 Feb 2021 14:27:11 -0500 Subject: [PATCH 1/4] Emit error when trying to use assembler syntax directives in `asm!` --- compiler/rustc_builtin_macros/src/asm.rs | 53 +++++++++++++++++++++++- src/test/ui/asm/inline-syntax.rs | 14 +++++++ src/test/ui/asm/inline-syntax.stderr | 36 ++++++++++++++++ 3 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/asm/inline-syntax.rs create mode 100644 src/test/ui/asm/inline-syntax.stderr diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index 36cd6c281b42a..168dee6678d68 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -7,7 +7,10 @@ use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_expand::base::{self, *}; use rustc_parse::parser::Parser; use rustc_parse_format as parse; -use rustc_span::symbol::{kw, sym, Symbol}; +use rustc_span::{ + symbol::{kw, sym, Symbol}, + BytePos, +}; use rustc_span::{InnerSpan, Span}; struct AsmArgs { @@ -465,6 +468,54 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P { + if let Some(idx) = s.find(".intel_syntax") { + let mut end = idx + ".intel_syntax".len(); + if let Some(prefix_idx) = s.split_at(end).1.find("noprefix") { + // Should be a space and it should be immediately after + if prefix_idx == 1 { + end += " noprefix".len(); + } + } + + let syntax_span = + template_span.from_inner(InnerSpan::new(idx + 1, end + 1)); + let mut err = ecx.struct_span_err(syntax_span, "intel sytnax is the default syntax, and trying to use this directive may cause issues"); + err.span_suggestion( + syntax_span, + "Remove this assembler directive", + s.replace(&s[idx..end], "").to_string(), + Applicability::MachineApplicable, + ); + err.emit(); + } + + if let Some(idx) = s.find(".att_syntax") { + let mut end = idx + ".att_syntax".len(); + if let Some(prefix_idx) = s.split_at(end).1.find("noprefix") { + // Should be a space and it should be immediately after + if prefix_idx == 1 { + end += " noprefix".len(); + } + } + + let syntax_span = + template_span.from_inner(InnerSpan::new(idx + 1, end + 1)); + let mut err = ecx.struct_span_err(syntax_span, "using the .att_syntax directive may cause issues, use the att_syntax option instead"); + let asm_end = sp.hi() - BytePos(2); + let suggestions = vec![ + (syntax_span, "".to_string()), + ( + Span::new(asm_end, asm_end, sp.ctxt()), + ", options(att_syntax)".to_string(), + ), + ]; + err.multipart_suggestion( + "Remove the assembler directive and replace it with options(att_syntax)", + suggestions, + Applicability::MachineApplicable, + ); + err.emit(); + } template.push(ast::InlineAsmTemplatePiece::String(s.to_string())) } parse::Piece::NextArgument(arg) => { diff --git a/src/test/ui/asm/inline-syntax.rs b/src/test/ui/asm/inline-syntax.rs new file mode 100644 index 0000000000000..ec8ff0718857b --- /dev/null +++ b/src/test/ui/asm/inline-syntax.rs @@ -0,0 +1,14 @@ +#![feature(asm, llvm_asm)] + +fn main() { + unsafe { + asm!(".intel_syntax noprefix", "nop"); + //~^ ERROR intel sytnax is the default syntax + asm!(".intel_syntax aaa noprefix", "nop"); + //~^ ERROR intel sytnax is the default syntax + asm!(".att_syntax noprefix", "nop"); + //~^ ERROR using the .att_syntax directive may cause issues + asm!(".att_syntax bbb noprefix", "nop"); + //~^ ERROR using the .att_syntax directive may cause issues + } +} diff --git a/src/test/ui/asm/inline-syntax.stderr b/src/test/ui/asm/inline-syntax.stderr new file mode 100644 index 0000000000000..bd792660c6ae4 --- /dev/null +++ b/src/test/ui/asm/inline-syntax.stderr @@ -0,0 +1,36 @@ +error: intel sytnax is the default syntax, and trying to use this directive may cause issues + --> $DIR/inline-syntax.rs:5:15 + | +LL | asm!(".intel_syntax noprefix", "nop"); + | ^^^^^^^^^^^^^^^^^^^^^^ help: Remove this assembler directive + +error: intel sytnax is the default syntax, and trying to use this directive may cause issues + --> $DIR/inline-syntax.rs:7:15 + | +LL | asm!(".intel_syntax aaa noprefix", "nop"); + | ^^^^^^^^^^^^^ help: Remove this assembler directive: `aaa noprefix` + +error: using the .att_syntax directive may cause issues, use the att_syntax option instead + --> $DIR/inline-syntax.rs:9:15 + | +LL | asm!(".att_syntax noprefix", "nop"); + | ^^^^^^^^^^^^^^^^^^^^ + | +help: Remove the assembler directive and replace it with options(att_syntax) + | +LL | asm!("", "nop", options(att_syntax)); + | -- ^^^^^^^^^^^^^^^^^^^^^ + +error: using the .att_syntax directive may cause issues, use the att_syntax option instead + --> $DIR/inline-syntax.rs:11:15 + | +LL | asm!(".att_syntax bbb noprefix", "nop"); + | ^^^^^^^^^^^ + | +help: Remove the assembler directive and replace it with options(att_syntax) + | +LL | asm!(" bbb noprefix", "nop", options(att_syntax)); + | -- ^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + From 39dcd01bf5e0c69c487f18903f44074f49ef205b Mon Sep 17 00:00:00 2001 From: asquared31415 <34665709+asquared31415@users.noreply.github.com> Date: Sat, 20 Feb 2021 01:17:18 -0500 Subject: [PATCH 2/4] Take into account target default syntax --- compiler/rustc_builtin_macros/src/asm.rs | 120 ++++++++++++++--------- src/test/ui/asm/inline-syntax.rs | 13 ++- src/test/ui/asm/inline-syntax.stderr | 34 +++++-- 3 files changed, 107 insertions(+), 60 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index 168dee6678d68..bb529f9e5c2b4 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -12,6 +12,7 @@ use rustc_span::{ BytePos, }; use rustc_span::{InnerSpan, Span}; +use rustc_target::asm::InlineAsmArch; struct AsmArgs { templates: Vec>, @@ -427,6 +428,65 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P ast::LlvmAsmDialect::Intel, + _ => ast::LlvmAsmDialect::Att, + }; + + let snippet = snippet.trim_matches('"'); + match default_dialect { + ast::LlvmAsmDialect::Intel => { + if let Some(span) = check_syntax_directive(snippet, ".intel_syntax") { + let span = template_span.from_inner(span); + let mut err = ecx.struct_span_err(span, "intel syntax is the default syntax on this target, and trying to use this directive may cause issues"); + err.span_suggestion( + span, + "remove this assembler directive", + "".to_string(), + Applicability::MachineApplicable, + ); + err.emit(); + } + + if let Some(span) = check_syntax_directive(snippet, ".att_syntax") { + let span = template_span.from_inner(span); + let mut err = ecx.struct_span_err(span, "using the .att_syntax directive may cause issues, use the att_syntax option instead"); + let asm_end = sp.hi() - BytePos(2); + let suggestions = vec![ + (span, "".to_string()), + ( + Span::new(asm_end, asm_end, sp.ctxt()), + ", options(att_syntax)".to_string(), + ), + ]; + err.multipart_suggestion( + "remove the assembler directive and replace it with options(att_syntax)", + suggestions, + Applicability::MachineApplicable, + ); + err.emit(); + } + } + ast::LlvmAsmDialect::Att => { + if let Some(span) = check_syntax_directive(snippet, ".att_syntax") { + let span = template_span.from_inner(span); + let mut err = ecx.struct_span_err(span, "att syntax is the default syntax on this target, and trying to use this directive may cause issues"); + err.span_suggestion( + span, + "remove this assembler directive", + "".to_string(), + Applicability::MachineApplicable, + ); + err.emit(); + } + + // Use of .intel_syntax is ignored + } + } + } + let mut parser = parse::Parser::new( template_str, str_style, @@ -468,54 +528,6 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P { - if let Some(idx) = s.find(".intel_syntax") { - let mut end = idx + ".intel_syntax".len(); - if let Some(prefix_idx) = s.split_at(end).1.find("noprefix") { - // Should be a space and it should be immediately after - if prefix_idx == 1 { - end += " noprefix".len(); - } - } - - let syntax_span = - template_span.from_inner(InnerSpan::new(idx + 1, end + 1)); - let mut err = ecx.struct_span_err(syntax_span, "intel sytnax is the default syntax, and trying to use this directive may cause issues"); - err.span_suggestion( - syntax_span, - "Remove this assembler directive", - s.replace(&s[idx..end], "").to_string(), - Applicability::MachineApplicable, - ); - err.emit(); - } - - if let Some(idx) = s.find(".att_syntax") { - let mut end = idx + ".att_syntax".len(); - if let Some(prefix_idx) = s.split_at(end).1.find("noprefix") { - // Should be a space and it should be immediately after - if prefix_idx == 1 { - end += " noprefix".len(); - } - } - - let syntax_span = - template_span.from_inner(InnerSpan::new(idx + 1, end + 1)); - let mut err = ecx.struct_span_err(syntax_span, "using the .att_syntax directive may cause issues, use the att_syntax option instead"); - let asm_end = sp.hi() - BytePos(2); - let suggestions = vec![ - (syntax_span, "".to_string()), - ( - Span::new(asm_end, asm_end, sp.ctxt()), - ", options(att_syntax)".to_string(), - ), - ]; - err.multipart_suggestion( - "Remove the assembler directive and replace it with options(att_syntax)", - suggestions, - Applicability::MachineApplicable, - ); - err.emit(); - } template.push(ast::InlineAsmTemplatePiece::String(s.to_string())) } parse::Piece::NextArgument(arg) => { @@ -682,3 +694,15 @@ pub fn expand_asm<'cx>( } } } + +fn check_syntax_directive>(piece: S, syntax: &str) -> Option { + let piece = piece.as_ref(); + if let Some(idx) = piece.find(syntax) { + let end = + idx + &piece[idx..].find(|c| matches!(c, '\n' | ';')).unwrap_or(piece[idx..].len()); + // Offset by one because these represent the span with the " removed + Some(InnerSpan::new(idx + 1, end + 1)) + } else { + None + } +} diff --git a/src/test/ui/asm/inline-syntax.rs b/src/test/ui/asm/inline-syntax.rs index ec8ff0718857b..31e7f2cc79662 100644 --- a/src/test/ui/asm/inline-syntax.rs +++ b/src/test/ui/asm/inline-syntax.rs @@ -3,12 +3,21 @@ fn main() { unsafe { asm!(".intel_syntax noprefix", "nop"); - //~^ ERROR intel sytnax is the default syntax + //~^ ERROR intel syntax is the default syntax on this target asm!(".intel_syntax aaa noprefix", "nop"); - //~^ ERROR intel sytnax is the default syntax + //~^ ERROR intel syntax is the default syntax on this target asm!(".att_syntax noprefix", "nop"); //~^ ERROR using the .att_syntax directive may cause issues asm!(".att_syntax bbb noprefix", "nop"); //~^ ERROR using the .att_syntax directive may cause issues + asm!(".intel_syntax noprefix; nop"); + //~^ ERROR intel syntax is the default syntax on this target + + asm!( + r" + .intel_syntax noprefix + nop" + ); + //~^^^ ERROR intel syntax is the default syntax on this target } } diff --git a/src/test/ui/asm/inline-syntax.stderr b/src/test/ui/asm/inline-syntax.stderr index bd792660c6ae4..241b302ad6472 100644 --- a/src/test/ui/asm/inline-syntax.stderr +++ b/src/test/ui/asm/inline-syntax.stderr @@ -1,14 +1,14 @@ -error: intel sytnax is the default syntax, and trying to use this directive may cause issues +error: intel syntax is the default syntax on this target, and trying to use this directive may cause issues --> $DIR/inline-syntax.rs:5:15 | LL | asm!(".intel_syntax noprefix", "nop"); - | ^^^^^^^^^^^^^^^^^^^^^^ help: Remove this assembler directive + | ^^^^^^^^^^^^^^^^^^^^^^ help: remove this assembler directive -error: intel sytnax is the default syntax, and trying to use this directive may cause issues +error: intel syntax is the default syntax on this target, and trying to use this directive may cause issues --> $DIR/inline-syntax.rs:7:15 | LL | asm!(".intel_syntax aaa noprefix", "nop"); - | ^^^^^^^^^^^^^ help: Remove this assembler directive: `aaa noprefix` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this assembler directive error: using the .att_syntax directive may cause issues, use the att_syntax option instead --> $DIR/inline-syntax.rs:9:15 @@ -16,7 +16,7 @@ error: using the .att_syntax directive may cause issues, use the att_syntax opti LL | asm!(".att_syntax noprefix", "nop"); | ^^^^^^^^^^^^^^^^^^^^ | -help: Remove the assembler directive and replace it with options(att_syntax) +help: remove the assembler directive and replace it with options(att_syntax) | LL | asm!("", "nop", options(att_syntax)); | -- ^^^^^^^^^^^^^^^^^^^^^ @@ -25,12 +25,26 @@ error: using the .att_syntax directive may cause issues, use the att_syntax opti --> $DIR/inline-syntax.rs:11:15 | LL | asm!(".att_syntax bbb noprefix", "nop"); - | ^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^ | -help: Remove the assembler directive and replace it with options(att_syntax) +help: remove the assembler directive and replace it with options(att_syntax) | -LL | asm!(" bbb noprefix", "nop", options(att_syntax)); - | -- ^^^^^^^^^^^^^^^^^^^^^ +LL | asm!("", "nop", options(att_syntax)); + | -- ^^^^^^^^^^^^^^^^^^^^^ + +error: intel syntax is the default syntax on this target, and trying to use this directive may cause issues + --> $DIR/inline-syntax.rs:13:15 + | +LL | asm!(".intel_syntax noprefix; nop"); + | ^^^^^^^^^^^^^^^^^^^^^^ help: remove this assembler directive + +error: intel syntax is the default syntax on this target, and trying to use this directive may cause issues + --> $DIR/inline-syntax.rs:18:14 + | +LL | .intel_syntax noprefix + | ______________^ +LL | | nop" + | |_ help: remove this assembler directive -error: aborting due to 4 previous errors +error: aborting due to 6 previous errors From 05ae66607fe2aaab786e6444f4b674499fd79319 Mon Sep 17 00:00:00 2001 From: asquared31415 <34665709+asquared31415@users.noreply.github.com> Date: Mon, 8 Mar 2021 12:16:12 -0500 Subject: [PATCH 3/4] Move default inline asm dialect to Session --- compiler/rustc_builtin_macros/src/asm.rs | 8 ++------ compiler/rustc_session/src/session.rs | 7 +++++++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index bb529f9e5c2b4..8d8b3f4f6aaac 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -12,7 +12,6 @@ use rustc_span::{ BytePos, }; use rustc_span::{InnerSpan, Span}; -use rustc_target::asm::InlineAsmArch; struct AsmArgs { templates: Vec>, @@ -403,6 +402,8 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P, sp: Span, args: AsmArgs) -> P ast::LlvmAsmDialect::Intel, - _ => ast::LlvmAsmDialect::Att, - }; - let snippet = snippet.trim_matches('"'); match default_dialect { ast::LlvmAsmDialect::Intel => { diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index a7ceb9e06a519..83ab066c7c3ad 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -784,6 +784,13 @@ impl Session { } } + pub fn inline_asm_dialect(&self) -> rustc_ast::LlvmAsmDialect { + match self.asm_arch { + Some(InlineAsmArch::X86 | InlineAsmArch::X86_64) => rustc_ast::LlvmAsmDialect::Intel, + _ => rustc_ast::LlvmAsmDialect::Att, + } + } + pub fn relocation_model(&self) -> RelocModel { self.opts.cg.relocation_model.unwrap_or(self.target.relocation_model) } From 4b13b8120e67e2b3173c8f6ce0d175847b745085 Mon Sep 17 00:00:00 2001 From: asquared31415 <34665709+asquared31415@users.noreply.github.com> Date: Mon, 8 Mar 2021 23:48:08 -0500 Subject: [PATCH 4/4] Test x86 and arm outputs --- src/test/ui/asm/inline-syntax.arm.stderr | 14 +++++++++ src/test/ui/asm/inline-syntax.rs | 29 ++++++++++++++----- ...tax.stderr => inline-syntax.x86_64.stderr} | 12 ++++---- 3 files changed, 42 insertions(+), 13 deletions(-) create mode 100644 src/test/ui/asm/inline-syntax.arm.stderr rename src/test/ui/asm/{inline-syntax.stderr => inline-syntax.x86_64.stderr} (89%) diff --git a/src/test/ui/asm/inline-syntax.arm.stderr b/src/test/ui/asm/inline-syntax.arm.stderr new file mode 100644 index 0000000000000..b1b61f0211a37 --- /dev/null +++ b/src/test/ui/asm/inline-syntax.arm.stderr @@ -0,0 +1,14 @@ +error: att syntax is the default syntax on this target, and trying to use this directive may cause issues + --> $DIR/inline-syntax.rs:22:15 + | +LL | asm!(".att_syntax noprefix", "nop"); + | ^^^^^^^^^^^^^^^^^^^^ help: remove this assembler directive + +error: att syntax is the default syntax on this target, and trying to use this directive may cause issues + --> $DIR/inline-syntax.rs:25:15 + | +LL | asm!(".att_syntax bbb noprefix", "nop"); + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this assembler directive + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/asm/inline-syntax.rs b/src/test/ui/asm/inline-syntax.rs index 31e7f2cc79662..9e9c7badfcace 100644 --- a/src/test/ui/asm/inline-syntax.rs +++ b/src/test/ui/asm/inline-syntax.rs @@ -1,23 +1,38 @@ -#![feature(asm, llvm_asm)] +// revisions: x86_64 arm +//[x86_64] compile-flags: --target x86_64-unknown-linux-gnu +//[arm] compile-flags: --target armv7-unknown-linux-gnueabihf + +#![feature(no_core, lang_items, rustc_attrs)] +#![no_core] + +#[rustc_builtin_macro] +macro_rules! asm { + () => {}; +} + +#[lang = "sized"] +trait Sized {} fn main() { unsafe { asm!(".intel_syntax noprefix", "nop"); - //~^ ERROR intel syntax is the default syntax on this target + //[x86_64]~^ ERROR intel syntax is the default syntax on this target asm!(".intel_syntax aaa noprefix", "nop"); - //~^ ERROR intel syntax is the default syntax on this target + //[x86_64]~^ ERROR intel syntax is the default syntax on this target asm!(".att_syntax noprefix", "nop"); - //~^ ERROR using the .att_syntax directive may cause issues + //[x86_64]~^ ERROR using the .att_syntax directive may cause issues + //[arm]~^^ att syntax is the default syntax on this target asm!(".att_syntax bbb noprefix", "nop"); - //~^ ERROR using the .att_syntax directive may cause issues + //[x86_64]~^ ERROR using the .att_syntax directive may cause issues + //[arm]~^^ att syntax is the default syntax on this target asm!(".intel_syntax noprefix; nop"); - //~^ ERROR intel syntax is the default syntax on this target + //[x86_64]~^ ERROR intel syntax is the default syntax on this target asm!( r" .intel_syntax noprefix nop" ); - //~^^^ ERROR intel syntax is the default syntax on this target + //[x86_64]~^^^ ERROR intel syntax is the default syntax on this target } } diff --git a/src/test/ui/asm/inline-syntax.stderr b/src/test/ui/asm/inline-syntax.x86_64.stderr similarity index 89% rename from src/test/ui/asm/inline-syntax.stderr rename to src/test/ui/asm/inline-syntax.x86_64.stderr index 241b302ad6472..c54c2742a5791 100644 --- a/src/test/ui/asm/inline-syntax.stderr +++ b/src/test/ui/asm/inline-syntax.x86_64.stderr @@ -1,17 +1,17 @@ error: intel syntax is the default syntax on this target, and trying to use this directive may cause issues - --> $DIR/inline-syntax.rs:5:15 + --> $DIR/inline-syntax.rs:18:15 | LL | asm!(".intel_syntax noprefix", "nop"); | ^^^^^^^^^^^^^^^^^^^^^^ help: remove this assembler directive error: intel syntax is the default syntax on this target, and trying to use this directive may cause issues - --> $DIR/inline-syntax.rs:7:15 + --> $DIR/inline-syntax.rs:20:15 | LL | asm!(".intel_syntax aaa noprefix", "nop"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this assembler directive error: using the .att_syntax directive may cause issues, use the att_syntax option instead - --> $DIR/inline-syntax.rs:9:15 + --> $DIR/inline-syntax.rs:22:15 | LL | asm!(".att_syntax noprefix", "nop"); | ^^^^^^^^^^^^^^^^^^^^ @@ -22,7 +22,7 @@ LL | asm!("", "nop", options(att_syntax)); | -- ^^^^^^^^^^^^^^^^^^^^^ error: using the .att_syntax directive may cause issues, use the att_syntax option instead - --> $DIR/inline-syntax.rs:11:15 + --> $DIR/inline-syntax.rs:25:15 | LL | asm!(".att_syntax bbb noprefix", "nop"); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,13 +33,13 @@ LL | asm!("", "nop", options(att_syntax)); | -- ^^^^^^^^^^^^^^^^^^^^^ error: intel syntax is the default syntax on this target, and trying to use this directive may cause issues - --> $DIR/inline-syntax.rs:13:15 + --> $DIR/inline-syntax.rs:28:15 | LL | asm!(".intel_syntax noprefix; nop"); | ^^^^^^^^^^^^^^^^^^^^^^ help: remove this assembler directive error: intel syntax is the default syntax on this target, and trying to use this directive may cause issues - --> $DIR/inline-syntax.rs:18:14 + --> $DIR/inline-syntax.rs:33:14 | LL | .intel_syntax noprefix | ______________^