Rollup merge of #82270 - asquared31415:asm-syntax-directive-errors, r=nagisa

Emit error when trying to use assembler syntax directives in `asm!`

The `.intel_syntax` and `.att_syntax` assembler directives should not be used, in favor of not specifying a syntax for intel, and in favor of the explicit `att_syntax` option using the inline assembly options.

Closes #79869
This commit is contained in:
Dylan DPC 2021-03-18 00:28:06 +01:00 committed by GitHub
commit 16f6583f2d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 181 additions and 1 deletions

View File

@ -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 {
@ -399,6 +402,8 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
let mut line_spans = Vec::with_capacity(args.templates.len());
let mut curarg = 0;
let default_dialect = ecx.sess.inline_asm_dialect();
for template_expr in args.templates.into_iter() {
if !template.is_empty() {
template.push(ast::InlineAsmTemplatePiece::String("\n".to_string()));
@ -424,6 +429,60 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
let template_str = &template_str.as_str();
let template_snippet = ecx.source_map().span_to_snippet(template_sp).ok();
if let Some(snippet) = &template_snippet {
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,
@ -631,3 +690,15 @@ pub fn expand_asm<'cx>(
}
}
}
fn check_syntax_directive<S: AsRef<str>>(piece: S, syntax: &str) -> Option<InnerSpan> {
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
}
}

View File

@ -793,6 +793,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)
}

View File

@ -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

View File

@ -0,0 +1,38 @@
// 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");
//[x86_64]~^ ERROR intel syntax is the default syntax on this target
asm!(".intel_syntax aaa noprefix", "nop");
//[x86_64]~^ ERROR intel syntax is the default syntax on this target
asm!(".att_syntax noprefix", "nop");
//[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");
//[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");
//[x86_64]~^ ERROR intel syntax is the default syntax on this target
asm!(
r"
.intel_syntax noprefix
nop"
);
//[x86_64]~^^^ ERROR intel syntax is the default syntax on this target
}
}

View File

@ -0,0 +1,50 @@
error: intel syntax is the default syntax on this target, and trying to use this directive may cause issues
--> $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: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:22: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:25:15
|
LL | asm!(".att_syntax bbb noprefix", "nop");
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
help: remove the assembler directive and replace it with 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: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:33:14
|
LL | .intel_syntax noprefix
| ______________^
LL | | nop"
| |_ help: remove this assembler directive
error: aborting due to 6 previous errors