Skip to content

Commit f8e2002

Browse files
committed
apply cfg everywhere except for the first template element
1 parent b4fb021 commit f8e2002

File tree

2 files changed

+127
-6
lines changed

2 files changed

+127
-6
lines changed

compiler/rustc_builtin_macros/src/asm.rs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,10 @@ pub fn parse_asm_args<'a>(
182182

183183
// Parse options
184184
if p.eat_keyword(exp!(Options)) {
185-
parse_options(p, &mut args, asm_macro)?;
186-
allow_templates = false;
185+
parse_options(p, &mut args, asm_macro, is_configured_out)?;
186+
if !is_configured_out {
187+
allow_templates = false;
188+
}
187189
continue;
188190
}
189191

@@ -194,7 +196,9 @@ pub fn parse_asm_args<'a>(
194196
let (ident, _) = p.token.ident().unwrap();
195197
p.bump();
196198
p.expect(exp!(Eq))?;
197-
allow_templates = false;
199+
if !is_configured_out {
200+
allow_templates = false;
201+
}
198202
Some(ident.name)
199203
} else {
200204
None
@@ -265,6 +269,11 @@ pub fn parse_asm_args<'a>(
265269
ast::InlineAsmOperand::Sym { sym }
266270
} else if allow_templates {
267271
let template = p.parse_expr()?;
272+
273+
if is_configured_out {
274+
continue;
275+
}
276+
268277
// If it can't possibly expand to a string, provide diagnostics here to include other
269278
// things it could have been.
270279
match template.kind {
@@ -288,6 +297,10 @@ pub fn parse_asm_args<'a>(
288297
p.unexpected_any()?
289298
};
290299

300+
if is_configured_out {
301+
continue;
302+
}
303+
291304
allow_templates = false;
292305
let span = span_start.to(p.prev_token.span);
293306
let slot = args.operands.len();
@@ -451,6 +464,7 @@ fn parse_options<'a>(
451464
p: &mut Parser<'a>,
452465
args: &mut AsmArgs,
453466
asm_macro: AsmMacro,
467+
is_configured_out: bool,
454468
) -> PResult<'a, ()> {
455469
let span_start = p.prev_token.span;
456470

@@ -478,7 +492,9 @@ fn parse_options<'a>(
478492
};
479493

480494
if kw_matched {
481-
try_set_option(p, args, asm_macro, exp.kw, option);
495+
if !is_configured_out {
496+
try_set_option(p, args, asm_macro, exp.kw, option);
497+
}
482498
break 'blk;
483499
}
484500
}
@@ -493,8 +509,10 @@ fn parse_options<'a>(
493509
p.expect(exp!(Comma))?;
494510
}
495511

496-
let new_span = span_start.to(p.prev_token.span);
497-
args.options_spans.push(new_span);
512+
if !is_configured_out {
513+
let new_span = span_start.to(p.prev_token.span);
514+
args.options_spans.push(new_span);
515+
}
498516

499517
Ok(())
500518
}

tests/ui/asm/cfg.rs

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// Check that `cfg` and `cfg_attr` work as expected.
2+
//
3+
//@ revisions: reva revb
4+
//@ only-x86_64
5+
//@ run-pass
6+
#![feature(asm_cfg, cfg_match)]
7+
8+
use std::arch::{asm, naked_asm};
9+
10+
#[unsafe(naked)]
11+
extern "C" fn ignore_const_operand() -> u64 {
12+
naked_asm!(
13+
"mov rax, 5",
14+
#[cfg(revb)]
15+
"mov rax, {a}",
16+
"ret",
17+
#[cfg(revb)]
18+
a = const 10,
19+
)
20+
}
21+
22+
#[unsafe(naked)]
23+
extern "C" fn ignore_const_operand_cfg_attr() -> u64 {
24+
naked_asm!(
25+
"mov rax, 5",
26+
#[cfg_attr(true, cfg(revb))]
27+
"mov rax, {a}",
28+
"ret",
29+
#[cfg_attr(true, cfg(revb))]
30+
a = const 10,
31+
)
32+
}
33+
34+
#[unsafe(naked)]
35+
extern "C" fn const_operand() -> u64 {
36+
naked_asm!(
37+
"mov rax, {a}",
38+
"ret",
39+
#[cfg(reva)]
40+
a = const 5,
41+
#[cfg(revb)]
42+
a = const 10,
43+
)
44+
}
45+
46+
fn options() {
47+
// Without the cfg, this throws an error that the `noreturn` option is provided twice.
48+
unsafe {
49+
asm!(
50+
"nop",
51+
#[cfg(false)]
52+
options(att_syntax),
53+
options(att_syntax)
54+
)
55+
}
56+
}
57+
58+
fn clobber_abi() {
59+
// Without the cfg, this throws an error that the "C" abi is provided twice.
60+
unsafe {
61+
asm!(
62+
"nop",
63+
#[cfg(false)]
64+
clobber_abi("C"),
65+
clobber_abi("C"),
66+
);
67+
}
68+
}
69+
70+
fn template_allowed() {
71+
// Without the cfg, templates are not allowed after operands.
72+
unsafe {
73+
asm!(
74+
"nop",
75+
#[cfg(false)]
76+
clobber_abi("C"),
77+
#[cfg(false)]
78+
options(att_syntax),
79+
#[cfg(false)]
80+
a = out(reg) x,
81+
"nop",
82+
);
83+
}
84+
}
85+
86+
pub fn main() {
87+
std::cfg_match! {
88+
reva => {
89+
assert_eq!(const_operand(), 5);
90+
assert_eq!(ignore_const_operand_cfg_attr(), 5);
91+
assert_eq!(ignore_const_operand(), 5);
92+
93+
}
94+
revb => {
95+
assert_eq!(const_operand(), 10);
96+
assert_eq!(ignore_const_operand_cfg_attr(), 10);
97+
assert_eq!(ignore_const_operand(), 10);
98+
}
99+
}
100+
options();
101+
clobber_abi();
102+
template_allowed();
103+
}

0 commit comments

Comments
 (0)