about summary refs log tree commit diff
path: root/clippy_lints/src/asm_syntax.rs
diff options
context:
space:
mode:
authorflip1995 <hello@philkrones.com>2020-10-09 12:45:29 +0200
committerflip1995 <hello@philkrones.com>2020-10-09 12:45:29 +0200
commitfbf2430f0279adb8132efe60b16f8dd7b6a2acb3 (patch)
tree3e66912301876dca6c85f7a0dc9feb03d6cd1fbe /clippy_lints/src/asm_syntax.rs
parentadb7fc6283711c881186ca85bb9ac3bb8add099b (diff)
Merge commit '2f6439ae6a6803d030cceb3ee14c9150e91b328b' into clippyup
Diffstat (limited to 'clippy_lints/src/asm_syntax.rs')
-rw-r--r--clippy_lints/src/asm_syntax.rs125
1 files changed, 125 insertions, 0 deletions
diff --git a/clippy_lints/src/asm_syntax.rs b/clippy_lints/src/asm_syntax.rs
new file mode 100644
index 00000000000..ef1f1a14afc
--- /dev/null
+++ b/clippy_lints/src/asm_syntax.rs
@@ -0,0 +1,125 @@
+use std::fmt;
+
+use crate::utils::span_lint_and_help;
+use rustc_ast::ast::{Expr, ExprKind, InlineAsmOptions};
+use rustc_lint::{EarlyContext, EarlyLintPass, Lint};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+
+#[derive(Clone, Copy, PartialEq, Eq)]
+enum AsmStyle {
+    Intel,
+    Att,
+}
+
+impl fmt::Display for AsmStyle {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            AsmStyle::Intel => f.write_str("Intel"),
+            AsmStyle::Att => f.write_str("AT&T"),
+        }
+    }
+}
+
+impl std::ops::Not for AsmStyle {
+    type Output = AsmStyle;
+
+    fn not(self) -> AsmStyle {
+        match self {
+            AsmStyle::Intel => AsmStyle::Att,
+            AsmStyle::Att => AsmStyle::Intel,
+        }
+    }
+}
+
+fn check_expr_asm_syntax(lint: &'static Lint, cx: &EarlyContext<'_>, expr: &Expr, check_for: AsmStyle) {
+    if let ExprKind::InlineAsm(ref inline_asm) = expr.kind {
+        let style = if inline_asm.options.contains(InlineAsmOptions::ATT_SYNTAX) {
+            AsmStyle::Att
+        } else {
+            AsmStyle::Intel
+        };
+
+        if style == check_for {
+            span_lint_and_help(
+                cx,
+                lint,
+                expr.span,
+                &format!("{} x86 assembly syntax used", style),
+                None,
+                &format!("use {} x86 assembly syntax", !style),
+            );
+        }
+    }
+}
+
+declare_clippy_lint! {
+    /// **What it does:** Checks for usage of Intel x86 assembly syntax.
+    ///
+    /// **Why is this bad?** The lint has been enabled to indicate a preference
+    /// for AT&T x86 assembly syntax.
+    ///
+    /// **Known problems:** None.
+    ///
+    /// **Example:**
+    ///
+    /// ```rust,no_run
+    /// # #![feature(asm)]
+    /// # unsafe { let ptr = "".as_ptr();
+    /// asm!("lea {}, [{}]", lateout(reg) _, in(reg) ptr);
+    /// # }
+    /// ```
+    /// Use instead:
+    /// ```rust,no_run
+    /// # #![feature(asm)]
+    /// # unsafe { let ptr = "".as_ptr();
+    /// asm!("lea ({}), {}", in(reg) ptr, lateout(reg) _, options(att_syntax));
+    /// # }
+    /// ```
+    pub INLINE_ASM_X86_INTEL_SYNTAX,
+    restriction,
+    "prefer AT&T x86 assembly syntax"
+}
+
+declare_lint_pass!(InlineAsmX86IntelSyntax => [INLINE_ASM_X86_INTEL_SYNTAX]);
+
+impl EarlyLintPass for InlineAsmX86IntelSyntax {
+    fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
+        check_expr_asm_syntax(Self::get_lints()[0], cx, expr, AsmStyle::Intel);
+    }
+}
+
+declare_clippy_lint! {
+    /// **What it does:** Checks for usage of AT&T x86 assembly syntax.
+    ///
+    /// **Why is this bad?** The lint has been enabled to indicate a preference
+    /// for Intel x86 assembly syntax.
+    ///
+    /// **Known problems:** None.
+    ///
+    /// **Example:**
+    ///
+    /// ```rust,no_run
+    /// # #![feature(asm)]
+    /// # unsafe { let ptr = "".as_ptr();
+    /// asm!("lea ({}), {}", in(reg) ptr, lateout(reg) _, options(att_syntax));
+    /// # }
+    /// ```
+    /// Use instead:
+    /// ```rust,no_run
+    /// # #![feature(asm)]
+    /// # unsafe { let ptr = "".as_ptr();
+    /// asm!("lea {}, [{}]", lateout(reg) _, in(reg) ptr);
+    /// # }
+    /// ```
+    pub INLINE_ASM_X86_ATT_SYNTAX,
+    restriction,
+    "prefer Intel x86 assembly syntax"
+}
+
+declare_lint_pass!(InlineAsmX86AttSyntax => [INLINE_ASM_X86_ATT_SYNTAX]);
+
+impl EarlyLintPass for InlineAsmX86AttSyntax {
+    fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
+        check_expr_asm_syntax(Self::get_lints()[0], cx, expr, AsmStyle::Att);
+    }
+}