Skip to content

Commit 5dabc80

Browse files
committed
Refactor #82270 as lint instead of an error
1 parent 2bd94f4 commit 5dabc80

File tree

6 files changed

+179
-118
lines changed

6 files changed

+179
-118
lines changed

compiler/rustc_builtin_macros/src/asm.rs

+30-65
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,10 @@ use rustc_errors::{Applicability, DiagnosticBuilder};
77
use rustc_expand::base::{self, *};
88
use rustc_parse::parser::Parser;
99
use rustc_parse_format as parse;
10-
use rustc_span::{
11-
symbol::{kw, sym, Symbol},
12-
BytePos,
13-
};
10+
use rustc_session::lint;
11+
use rustc_span::symbol::{kw, sym, Symbol};
1412
use rustc_span::{InnerSpan, Span};
13+
use rustc_target::asm::InlineAsmArch;
1514

1615
struct AsmArgs {
1716
templates: Vec<P<ast::Expr>>,
@@ -402,8 +401,6 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
402401
let mut line_spans = Vec::with_capacity(args.templates.len());
403402
let mut curarg = 0;
404403

405-
let default_dialect = ecx.sess.inline_asm_dialect();
406-
407404
for template_expr in args.templates.into_iter() {
408405
if !template.is_empty() {
409406
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
430427
let template_str = &template_str.as_str();
431428
let template_snippet = ecx.source_map().span_to_snippet(template_sp).ok();
432429

433-
if let Some(snippet) = &template_snippet {
434-
let snippet = snippet.trim_matches('"');
435-
match default_dialect {
436-
ast::LlvmAsmDialect::Intel => {
437-
if let Some(span) = check_syntax_directive(snippet, ".intel_syntax") {
438-
let span = template_span.from_inner(span);
439-
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");
440-
err.span_suggestion(
441-
span,
442-
"remove this assembler directive",
443-
"".to_string(),
444-
Applicability::MachineApplicable,
445-
);
446-
err.emit();
447-
}
448-
449-
if let Some(span) = check_syntax_directive(snippet, ".att_syntax") {
450-
let span = template_span.from_inner(span);
451-
let mut err = ecx.struct_span_err(span, "using the .att_syntax directive may cause issues, use the att_syntax option instead");
452-
let asm_end = sp.hi() - BytePos(2);
453-
let suggestions = vec![
454-
(span, "".to_string()),
455-
(
456-
Span::new(asm_end, asm_end, sp.ctxt()),
457-
", options(att_syntax)".to_string(),
458-
),
459-
];
460-
err.multipart_suggestion(
461-
"remove the assembler directive and replace it with options(att_syntax)",
462-
suggestions,
463-
Applicability::MachineApplicable,
464-
);
465-
err.emit();
430+
if let Some(InlineAsmArch::X86 | InlineAsmArch::X86_64) = ecx.sess.asm_arch {
431+
let find_span = |needle: &str| -> Span {
432+
if let Some(snippet) = &template_snippet {
433+
if let Some(pos) = snippet.find(needle) {
434+
let end = pos
435+
+ &snippet[pos..]
436+
.find(|c| matches!(c, '\n' | ';' | '\\' | '"'))
437+
.unwrap_or(snippet[pos..].len() - 1);
438+
let inner = InnerSpan::new(pos, end);
439+
return template_sp.from_inner(inner);
466440
}
467441
}
468-
ast::LlvmAsmDialect::Att => {
469-
if let Some(span) = check_syntax_directive(snippet, ".att_syntax") {
470-
let span = template_span.from_inner(span);
471-
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");
472-
err.span_suggestion(
473-
span,
474-
"remove this assembler directive",
475-
"".to_string(),
476-
Applicability::MachineApplicable,
477-
);
478-
err.emit();
479-
}
442+
template_sp
443+
};
480444

481-
// Use of .intel_syntax is ignored
482-
}
445+
if template_str.contains(".intel_syntax") {
446+
ecx.parse_sess().buffer_lint(
447+
lint::builtin::BAD_ASM_STYLE,
448+
find_span(".intel_syntax"),
449+
ecx.resolver.lint_node_id(ecx.current_expansion.id),
450+
"avoid using `.intel_syntax`, Intel syntax is the default",
451+
);
452+
}
453+
if template_str.contains(".att_syntax") {
454+
ecx.parse_sess().buffer_lint(
455+
lint::builtin::BAD_ASM_STYLE,
456+
find_span(".att_syntax"),
457+
ecx.resolver.lint_node_id(ecx.current_expansion.id),
458+
"avoid using `.att_syntax`, prefer using `options(att_syntax)` instead",
459+
);
483460
}
484461
}
485462

@@ -690,15 +667,3 @@ pub fn expand_asm<'cx>(
690667
}
691668
}
692669
}
693-
694-
fn check_syntax_directive<S: AsRef<str>>(piece: S, syntax: &str) -> Option<InnerSpan> {
695-
let piece = piece.as_ref();
696-
if let Some(idx) = piece.find(syntax) {
697-
let end =
698-
idx + &piece[idx..].find(|c| matches!(c, '\n' | ';')).unwrap_or(piece[idx..].len());
699-
// Offset by one because these represent the span with the " removed
700-
Some(InnerSpan::new(idx + 1, end + 1))
701-
} else {
702-
None
703-
}
704-
}

compiler/rustc_lint_defs/src/builtin.rs

+46
Original file line numberDiff line numberDiff line change
@@ -2486,6 +2486,52 @@ declare_lint! {
24862486
"using only a subset of a register for inline asm inputs",
24872487
}
24882488

2489+
declare_lint! {
2490+
/// The `bad_asm_style` lint detects the use of the `.intel_syntax` and
2491+
/// `.att_syntax` directives.
2492+
///
2493+
/// ### Example
2494+
///
2495+
/// ```rust,ignore (fails on system llvm)
2496+
/// #![feature(asm)]
2497+
///
2498+
/// fn main() {
2499+
/// #[cfg(target_arch="x86_64")]
2500+
/// unsafe {
2501+
/// asm!(
2502+
/// ".att_syntax",
2503+
/// "movl {0}, {0}", in(reg) 0usize
2504+
/// );
2505+
/// }
2506+
/// }
2507+
/// ```
2508+
///
2509+
/// This will produce:
2510+
///
2511+
/// ```text
2512+
/// warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead
2513+
/// --> test.rs:7:14
2514+
/// |
2515+
/// 7 | ".att_syntax",
2516+
/// | ^^^^^^^^^^^
2517+
/// 8 | "movq {0}, {0}", out(reg) _,
2518+
/// 9 | );
2519+
/// | - help: add option: `, options(att_syntax)`
2520+
/// |
2521+
/// = note: `#[warn(bad_asm_style)]` on by default
2522+
/// ```
2523+
///
2524+
/// ### Explanation
2525+
///
2526+
/// On x86, `asm!` uses the intel assembly syntax by default. While this
2527+
/// can be switched using assembler directives like `.att_syntax`, using the
2528+
/// `att_syntax` option is recomended instead because it will also properly
2529+
/// prefix register placeholders with `%` as required by AT&T syntax.
2530+
pub BAD_ASM_STYLE,
2531+
Warn,
2532+
"incorrect use of inline assembly",
2533+
}
2534+
24892535
declare_lint! {
24902536
/// The `unsafe_op_in_unsafe_fn` lint detects unsafe operations in unsafe
24912537
/// functions without an explicit unsafe block.

compiler/rustc_session/src/session.rs

-7
Original file line numberDiff line numberDiff line change
@@ -793,13 +793,6 @@ impl Session {
793793
}
794794
}
795795

796-
pub fn inline_asm_dialect(&self) -> rustc_ast::LlvmAsmDialect {
797-
match self.asm_arch {
798-
Some(InlineAsmArch::X86 | InlineAsmArch::X86_64) => rustc_ast::LlvmAsmDialect::Intel,
799-
_ => rustc_ast::LlvmAsmDialect::Att,
800-
}
801-
}
802-
803796
pub fn relocation_model(&self) -> RelocModel {
804797
self.opts.cg.relocation_model.unwrap_or(self.target.relocation_model)
805798
}
+67-7
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,74 @@
1-
error: att syntax is the default syntax on this target, and trying to use this directive may cause issues
2-
--> $DIR/inline-syntax.rs:23:15
1+
error: unknown directive
2+
--> $DIR/inline-syntax.rs:22:15
3+
|
4+
LL | asm!(".intel_syntax noprefix", "nop");
5+
| ^
6+
|
7+
note: instantiated into assembly here
8+
--> <inline asm>:1:2
9+
|
10+
LL | .intel_syntax noprefix
11+
| ^
12+
13+
error: unknown directive
14+
--> $DIR/inline-syntax.rs:25:15
15+
|
16+
LL | asm!(".intel_syntax aaa noprefix", "nop");
17+
| ^
18+
|
19+
note: instantiated into assembly here
20+
--> <inline asm>:1:2
21+
|
22+
LL | .intel_syntax aaa noprefix
23+
| ^
24+
25+
error: unknown directive
26+
--> $DIR/inline-syntax.rs:28:15
327
|
428
LL | asm!(".att_syntax noprefix", "nop");
5-
| ^^^^^^^^^^^^^^^^^^^^ help: remove this assembler directive
29+
| ^
30+
|
31+
note: instantiated into assembly here
32+
--> <inline asm>:1:2
33+
|
34+
LL | .att_syntax noprefix
35+
| ^
636

7-
error: att syntax is the default syntax on this target, and trying to use this directive may cause issues
8-
--> $DIR/inline-syntax.rs:26:15
37+
error: unknown directive
38+
--> $DIR/inline-syntax.rs:31:15
939
|
1040
LL | asm!(".att_syntax bbb noprefix", "nop");
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this assembler directive
41+
| ^
42+
|
43+
note: instantiated into assembly here
44+
--> <inline asm>:1:2
45+
|
46+
LL | .att_syntax bbb noprefix
47+
| ^
48+
49+
error: unknown directive
50+
--> $DIR/inline-syntax.rs:34:15
51+
|
52+
LL | asm!(".intel_syntax noprefix; nop");
53+
| ^
54+
|
55+
note: instantiated into assembly here
56+
--> <inline asm>:1:2
57+
|
58+
LL | .intel_syntax noprefix; nop
59+
| ^
60+
61+
error: unknown directive
62+
--> $DIR/inline-syntax.rs:40:13
63+
|
64+
LL | .intel_syntax noprefix
65+
| ^
66+
|
67+
note: instantiated into assembly here
68+
--> <inline asm>:2:13
69+
|
70+
LL | .intel_syntax noprefix
71+
| ^
1272

13-
error: aborting due to 2 previous errors
73+
error: aborting due to 6 previous errors
1474

src/test/ui/asm/inline-syntax.rs

+16-9
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
// needs-llvm-components: arm
22
// revisions: x86_64 arm
33
//[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
4+
//[x86_64] check-pass
45
//[arm] compile-flags: --target armv7-unknown-linux-gnueabihf
6+
//[arm] build-fail
57

68
#![feature(no_core, lang_items, rustc_attrs)]
9+
#![crate_type = "rlib"]
710
#![no_core]
811

912
#[rustc_builtin_macro]
@@ -14,26 +17,30 @@ macro_rules! asm {
1417
#[lang = "sized"]
1518
trait Sized {}
1619

17-
fn main() {
20+
pub fn main() {
1821
unsafe {
1922
asm!(".intel_syntax noprefix", "nop");
20-
//[x86_64]~^ ERROR intel syntax is the default syntax on this target
23+
//[x86_64]~^ WARN avoid using `.intel_syntax`
24+
//[arm]~^^ ERROR unknown directive
2125
asm!(".intel_syntax aaa noprefix", "nop");
22-
//[x86_64]~^ ERROR intel syntax is the default syntax on this target
26+
//[x86_64]~^ WARN avoid using `.intel_syntax`
27+
//[arm]~^^ ERROR unknown directive
2328
asm!(".att_syntax noprefix", "nop");
24-
//[x86_64]~^ ERROR using the .att_syntax directive may cause issues
25-
//[arm]~^^ att syntax is the default syntax on this target
29+
//[x86_64]~^ WARN avoid using `.att_syntax`
30+
//[arm]~^^ ERROR unknown directive
2631
asm!(".att_syntax bbb noprefix", "nop");
27-
//[x86_64]~^ ERROR using the .att_syntax directive may cause issues
28-
//[arm]~^^ att syntax is the default syntax on this target
32+
//[x86_64]~^ WARN avoid using `.att_syntax`
33+
//[arm]~^^ ERROR unknown directive
2934
asm!(".intel_syntax noprefix; nop");
30-
//[x86_64]~^ ERROR intel syntax is the default syntax on this target
35+
//[x86_64]~^ WARN avoid using `.intel_syntax`
36+
//[arm]~^^ ERROR unknown directive
3137

3238
asm!(
3339
r"
3440
.intel_syntax noprefix
3541
nop"
3642
);
37-
//[x86_64]~^^^ ERROR intel syntax is the default syntax on this target
43+
//[x86_64]~^^^ WARN avoid using `.intel_syntax`
44+
//[arm]~^^^^ ERROR unknown directive
3845
}
3946
}
+20-30
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,40 @@
1-
error: intel syntax is the default syntax on this target, and trying to use this directive may cause issues
2-
--> $DIR/inline-syntax.rs:19:15
1+
warning: avoid using `.intel_syntax`, Intel syntax is the default
2+
--> $DIR/inline-syntax.rs:22:15
33
|
44
LL | asm!(".intel_syntax noprefix", "nop");
5-
| ^^^^^^^^^^^^^^^^^^^^^^ help: remove this assembler directive
5+
| ^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: `#[warn(bad_asm_style)]` on by default
68

7-
error: intel syntax is the default syntax on this target, and trying to use this directive may cause issues
8-
--> $DIR/inline-syntax.rs:21:15
9+
warning: avoid using `.intel_syntax`, Intel syntax is the default
10+
--> $DIR/inline-syntax.rs:25:15
911
|
1012
LL | asm!(".intel_syntax aaa noprefix", "nop");
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this assembler directive
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
1214

13-
error: using the .att_syntax directive may cause issues, use the att_syntax option instead
14-
--> $DIR/inline-syntax.rs:23:15
15+
warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead
16+
--> $DIR/inline-syntax.rs:28:15
1517
|
1618
LL | asm!(".att_syntax noprefix", "nop");
1719
| ^^^^^^^^^^^^^^^^^^^^
18-
|
19-
help: remove the assembler directive and replace it with options(att_syntax)
20-
|
21-
LL | asm!("", "nop", options(att_syntax));
22-
| -- ^^^^^^^^^^^^^^^^^^^^^
2320

24-
error: using the .att_syntax directive may cause issues, use the att_syntax option instead
25-
--> $DIR/inline-syntax.rs:26:15
21+
warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead
22+
--> $DIR/inline-syntax.rs:31:15
2623
|
2724
LL | asm!(".att_syntax bbb noprefix", "nop");
2825
| ^^^^^^^^^^^^^^^^^^^^^^^^
29-
|
30-
help: remove the assembler directive and replace it with options(att_syntax)
31-
|
32-
LL | asm!("", "nop", options(att_syntax));
33-
| -- ^^^^^^^^^^^^^^^^^^^^^
3426

35-
error: intel syntax is the default syntax on this target, and trying to use this directive may cause issues
36-
--> $DIR/inline-syntax.rs:29:15
27+
warning: avoid using `.intel_syntax`, Intel syntax is the default
28+
--> $DIR/inline-syntax.rs:34:15
3729
|
3830
LL | asm!(".intel_syntax noprefix; nop");
39-
| ^^^^^^^^^^^^^^^^^^^^^^ help: remove this assembler directive
31+
| ^^^^^^^^^^^^^^^^^^^^^^
4032

41-
error: intel syntax is the default syntax on this target, and trying to use this directive may cause issues
42-
--> $DIR/inline-syntax.rs:34:14
33+
warning: avoid using `.intel_syntax`, Intel syntax is the default
34+
--> $DIR/inline-syntax.rs:40:13
4335
|
44-
LL | .intel_syntax noprefix
45-
| ______________^
46-
LL | | nop"
47-
| |_ help: remove this assembler directive
36+
LL | .intel_syntax noprefix
37+
| ^^^^^^^^^^^^^^^^^^^^^^
4838

49-
error: aborting due to 6 previous errors
39+
warning: 6 warnings emitted
5040

0 commit comments

Comments
 (0)