-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
Copy pathasm_syntax.rs
154 lines (139 loc) · 4.64 KB
/
asm_syntax.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
use std::fmt;
use clippy_utils::diagnostics::span_lint_and_then;
use rustc_ast::ast::{Expr, ExprKind, InlineAsmOptions};
use rustc_ast::{InlineAsm, Item, ItemKind};
use rustc_lint::{EarlyContext, EarlyLintPass, Lint, LintContext};
use rustc_session::declare_lint_pass;
use rustc_span::Span;
use rustc_target::asm::InlineAsmArch;
#[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_asm_syntax(
lint: &'static Lint,
cx: &EarlyContext<'_>,
inline_asm: &InlineAsm,
span: Span,
check_for: AsmStyle,
) {
if matches!(cx.sess().asm_arch, Some(InlineAsmArch::X86 | InlineAsmArch::X86_64)) {
let style = if inline_asm.options.contains(InlineAsmOptions::ATT_SYNTAX) {
AsmStyle::Att
} else {
AsmStyle::Intel
};
if style == check_for {
#[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
span_lint_and_then(cx, lint, span, format!("{style} x86 assembly syntax used"), |diag| {
diag.help(format!("use {} x86 assembly syntax", !style));
});
}
}
}
declare_clippy_lint! {
/// ### What it does
/// Checks for usage of Intel x86 assembly syntax.
///
/// ### Why restrict this?
/// To enforce consistent use of AT&T x86 assembly syntax.
///
/// ### Example
///
/// ```rust,no_run
/// # #![feature(asm)]
/// # #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
/// # unsafe { let ptr = "".as_ptr();
/// # use std::arch::asm;
/// asm!("lea {}, [{}]", lateout(reg) _, in(reg) ptr);
/// # }
/// ```
/// Use instead:
/// ```rust,no_run
/// # #![feature(asm)]
/// # #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
/// # unsafe { let ptr = "".as_ptr();
/// # use std::arch::asm;
/// asm!("lea ({}), {}", in(reg) ptr, lateout(reg) _, options(att_syntax));
/// # }
/// ```
#[clippy::version = "1.49.0"]
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) {
if let ExprKind::InlineAsm(inline_asm) = &expr.kind {
check_asm_syntax(INLINE_ASM_X86_INTEL_SYNTAX, cx, inline_asm, expr.span, AsmStyle::Intel);
}
}
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
if let ItemKind::GlobalAsm(inline_asm) = &item.kind {
check_asm_syntax(INLINE_ASM_X86_INTEL_SYNTAX, cx, inline_asm, item.span, AsmStyle::Intel);
}
}
}
declare_clippy_lint! {
/// ### What it does
/// Checks for usage of AT&T x86 assembly syntax.
///
/// ### Why restrict this?
/// To enforce consistent use of Intel x86 assembly syntax.
///
/// ### Example
///
/// ```rust,no_run
/// # #![feature(asm)]
/// # #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
/// # unsafe { let ptr = "".as_ptr();
/// # use std::arch::asm;
/// asm!("lea ({}), {}", in(reg) ptr, lateout(reg) _, options(att_syntax));
/// # }
/// ```
/// Use instead:
/// ```rust,no_run
/// # #![feature(asm)]
/// # #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
/// # unsafe { let ptr = "".as_ptr();
/// # use std::arch::asm;
/// asm!("lea {}, [{}]", lateout(reg) _, in(reg) ptr);
/// # }
/// ```
#[clippy::version = "1.49.0"]
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) {
if let ExprKind::InlineAsm(inline_asm) = &expr.kind {
check_asm_syntax(INLINE_ASM_X86_ATT_SYNTAX, cx, inline_asm, expr.span, AsmStyle::Att);
}
}
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
if let ItemKind::GlobalAsm(inline_asm) = &item.kind {
check_asm_syntax(INLINE_ASM_X86_ATT_SYNTAX, cx, inline_asm, item.span, AsmStyle::Att);
}
}
}