]> git.proxmox.com Git - rustc.git/blobdiff - compiler/rustc_builtin_macros/src/asm.rs
New upstream version 1.53.0+dfsg1
[rustc.git] / compiler / rustc_builtin_macros / src / asm.rs
index 8d8b3f4f6aaaceb955cbe3b670289ff118e244f8..fd976b119b748bcf8a9a8dd30d814d4e6ea4c654 100644 (file)
@@ -7,11 +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},
-    BytePos,
-};
+use rustc_session::lint;
+use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_span::{InnerSpan, Span};
+use rustc_target::asm::InlineAsmArch;
 
 struct AsmArgs {
     templates: Vec<P<ast::Expr>>,
@@ -137,8 +136,8 @@ fn parse_args<'a>(
                 ast::InlineAsmOperand::InOut { reg, expr, late: true }
             }
         } else if p.eat_keyword(kw::Const) {
-            let expr = p.parse_expr()?;
-            ast::InlineAsmOperand::Const { expr }
+            let anon_const = p.parse_anon_const_expr()?;
+            ast::InlineAsmOperand::Const { anon_const }
         } else if p.eat_keyword(sym::sym) {
             let expr = p.parse_expr()?;
             match expr.kind {
@@ -402,8 +401,6 @@ 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()));
@@ -430,56 +427,36 @@ 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();
+        if let Some(InlineAsmArch::X86 | InlineAsmArch::X86_64) = ecx.sess.asm_arch {
+            let find_span = |needle: &str| -> Span {
+                if let Some(snippet) = &template_snippet {
+                    if let Some(pos) = snippet.find(needle) {
+                        let end = pos
+                            + &snippet[pos..]
+                                .find(|c| matches!(c, '\n' | ';' | '\\' | '"'))
+                                .unwrap_or(snippet[pos..].len() - 1);
+                        let inner = InnerSpan::new(pos, end);
+                        return template_sp.from_inner(inner);
                     }
                 }
-                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();
-                    }
+                template_sp
+            };
 
-                    // Use of .intel_syntax is ignored
-                }
+            if template_str.contains(".intel_syntax") {
+                ecx.parse_sess().buffer_lint(
+                    lint::builtin::BAD_ASM_STYLE,
+                    find_span(".intel_syntax"),
+                    ecx.resolver.lint_node_id(ecx.current_expansion.id),
+                    "avoid using `.intel_syntax`, Intel syntax is the default",
+                );
+            }
+            if template_str.contains(".att_syntax") {
+                ecx.parse_sess().buffer_lint(
+                    lint::builtin::BAD_ASM_STYLE,
+                    find_span(".att_syntax"),
+                    ecx.resolver.lint_node_id(ecx.current_expansion.id),
+                    "avoid using `.att_syntax`, prefer using `options(att_syntax)` instead",
+                );
             }
         }
 
@@ -690,15 +667,3 @@ 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
-    }
-}