Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 2be403c

Browse files
committed
Warn on duplicate asm! options
1 parent 820bba1 commit 2be403c

File tree

1 file changed

+58
-7
lines changed
  • src/librustc_builtin_macros

1 file changed

+58
-7
lines changed

src/librustc_builtin_macros/asm.rs

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ struct AsmArgs {
1919
options_spans: Vec<Span>,
2020
}
2121

22+
impl AsmArgs {
23+
fn option_is_set(&self, option: ast::InlineAsmOptions) -> bool {
24+
(self.options & option) == option
25+
}
26+
}
27+
2228
fn parse_args<'a>(
2329
ecx: &mut ExtCtxt<'a>,
2430
sp: Span,
@@ -283,27 +289,72 @@ fn parse_args<'a>(
283289
Ok(args)
284290
}
285291

292+
fn warn_duplicate_option<'a>(p: &mut Parser<'a>, span: Span) {
293+
let mut warn = if let Ok(snippet) = p.sess.source_map().span_to_snippet(span) {
294+
p.sess
295+
.span_diagnostic
296+
.struct_span_warn(span, &format!("the `{}` option was already provided", snippet))
297+
} else {
298+
p.sess.span_diagnostic.struct_span_warn(span, "this option was already provided")
299+
};
300+
warn.span_suggestion(
301+
span,
302+
"remove this option",
303+
String::new(),
304+
Applicability::MachineApplicable,
305+
);
306+
warn.emit();
307+
}
308+
286309
fn parse_options<'a>(p: &mut Parser<'a>, args: &mut AsmArgs) -> Result<(), DiagnosticBuilder<'a>> {
287310
let span_start = p.prev_token.span;
288311

289312
p.expect(&token::OpenDelim(token::DelimToken::Paren))?;
290313

291314
while !p.eat(&token::CloseDelim(token::DelimToken::Paren)) {
292315
if p.eat(&token::Ident(sym::pure, false)) {
293-
args.options |= ast::InlineAsmOptions::PURE;
316+
if !args.option_is_set(ast::InlineAsmOptions::PURE) {
317+
args.options |= ast::InlineAsmOptions::PURE;
318+
} else {
319+
warn_duplicate_option(p, p.prev_token.span);
320+
}
294321
} else if p.eat(&token::Ident(sym::nomem, false)) {
295-
args.options |= ast::InlineAsmOptions::NOMEM;
322+
if !args.option_is_set(ast::InlineAsmOptions::NOMEM) {
323+
args.options |= ast::InlineAsmOptions::NOMEM;
324+
} else {
325+
warn_duplicate_option(p, p.prev_token.span);
326+
}
296327
} else if p.eat(&token::Ident(sym::readonly, false)) {
297-
args.options |= ast::InlineAsmOptions::READONLY;
328+
if !args.option_is_set(ast::InlineAsmOptions::READONLY) {
329+
args.options |= ast::InlineAsmOptions::READONLY;
330+
} else {
331+
warn_duplicate_option(p, p.prev_token.span);
332+
}
298333
} else if p.eat(&token::Ident(sym::preserves_flags, false)) {
299-
args.options |= ast::InlineAsmOptions::PRESERVES_FLAGS;
334+
if !args.option_is_set(ast::InlineAsmOptions::PRESERVES_FLAGS) {
335+
args.options |= ast::InlineAsmOptions::PRESERVES_FLAGS;
336+
} else {
337+
warn_duplicate_option(p, p.prev_token.span);
338+
}
300339
} else if p.eat(&token::Ident(sym::noreturn, false)) {
301-
args.options |= ast::InlineAsmOptions::NORETURN;
340+
if !args.option_is_set(ast::InlineAsmOptions::NORETURN) {
341+
args.options |= ast::InlineAsmOptions::NORETURN;
342+
} else {
343+
warn_duplicate_option(p, p.prev_token.span);
344+
}
302345
} else if p.eat(&token::Ident(sym::nostack, false)) {
303-
args.options |= ast::InlineAsmOptions::NOSTACK;
346+
if !args.option_is_set(ast::InlineAsmOptions::NOSTACK) {
347+
args.options |= ast::InlineAsmOptions::NOSTACK;
348+
} else {
349+
warn_duplicate_option(p, p.prev_token.span);
350+
}
304351
} else {
305352
p.expect(&token::Ident(sym::att_syntax, false))?;
306-
args.options |= ast::InlineAsmOptions::ATT_SYNTAX;
353+
if !args.option_is_set(ast::InlineAsmOptions::ATT_SYNTAX) {
354+
args.options |= ast::InlineAsmOptions::ATT_SYNTAX;
355+
} else {
356+
warn_duplicate_option(p, p.prev_token.span);
357+
}
307358
}
308359

309360
// Allow trailing commas

0 commit comments

Comments
 (0)