@@ -10,13 +10,14 @@ use rustc_index::bit_set::GrowableBitSet;
1010use rustc_parse:: exp;
1111use rustc_parse:: parser:: { ExpKeywordPair , Parser } ;
1212use rustc_session:: lint;
13- use rustc_span:: { ErrorGuaranteed , InnerSpan , Span , Symbol , kw} ;
13+ use rustc_session:: parse:: feature_err;
14+ use rustc_span:: { ErrorGuaranteed , InnerSpan , Span , Symbol , kw, sym} ;
1415use rustc_target:: asm:: InlineAsmArch ;
1516use smallvec:: smallvec;
1617use { rustc_ast as ast, rustc_parse_format as parse} ;
1718
18- use crate :: errors;
1919use crate :: util:: { ExprToSpannedString , expr_to_spanned_string} ;
20+ use crate :: { errors, fluent_generated as fluent} ;
2021
2122pub struct AsmArgs {
2223 pub templates : Vec < P < ast:: Expr > > ,
@@ -59,19 +60,47 @@ fn eat_operand_keyword<'a>(
5960 }
6061}
6162
63+ /// A parsed list of attributes that is not attached to any item.
64+ /// Used to check whether `asm!` arguments are configured out.
65+ struct AsmAttrList ( ast:: AttrVec ) ;
66+
67+ impl AsmAttrList {
68+ fn parse < ' a > ( ecx : & ExtCtxt < ' a > , p : & mut Parser < ' a > ) -> PResult < ' a , Self > {
69+ let span_start = p. token . span ;
70+
71+ let mut attributes = ast:: AttrVec :: new ( ) ;
72+ loop {
73+ if p. token != token:: Pound {
74+ break ;
75+ }
76+
77+ let attr = p. parse_attribute ( rustc_parse:: parser:: attr:: InnerAttrPolicy :: Permitted ) ?;
78+ attributes. push ( attr) ;
79+ }
80+
81+ if !attributes. is_empty ( ) && !ecx. ecfg . features . asm_cfg ( ) {
82+ let span = span_start. to ( p. prev_token . span ) ;
83+ feature_err ( ecx. sess , sym:: asm_cfg, span, fluent:: builtin_macros_asm_cfg) . emit ( ) ;
84+ }
85+
86+ Ok ( Self ( attributes) )
87+ }
88+ }
89+
6290fn parse_args < ' a > (
6391 ecx : & ExtCtxt < ' a > ,
6492 sp : Span ,
6593 tts : TokenStream ,
6694 asm_macro : AsmMacro ,
6795) -> PResult < ' a , AsmArgs > {
6896 let mut p = ecx. new_parser_from_tts ( tts) ;
69- parse_asm_args ( & mut p, sp, asm_macro)
97+ parse_asm_args ( ecx , & mut p, sp, asm_macro)
7098}
7199
72100// Primarily public for rustfmt consumption.
73101// Internal consumers should continue to leverage `expand_asm`/`expand__global_asm`
74102pub fn parse_asm_args < ' a > (
103+ ecx : & ExtCtxt < ' a > ,
75104 p : & mut Parser < ' a > ,
76105 sp : Span ,
77106 asm_macro : AsmMacro ,
@@ -82,6 +111,7 @@ pub fn parse_asm_args<'a>(
82111 return Err ( dcx. create_err ( errors:: AsmRequiresTemplate { span : sp } ) ) ;
83112 }
84113
114+ let _attributes = AsmAttrList :: parse ( ecx, p) ?;
85115 let first_template = p. parse_expr ( ) ?;
86116 let mut args = AsmArgs {
87117 templates : vec ! [ first_template] ,
@@ -108,6 +138,8 @@ pub fn parse_asm_args<'a>(
108138 break ;
109139 } // accept trailing commas
110140
141+ let _attributes = AsmAttrList :: parse ( ecx, p) ?;
142+
111143 // Parse clobber_abi
112144 if p. eat_keyword ( exp ! ( ClobberAbi ) ) {
113145 parse_clobber_abi ( p, & mut args) ?;
0 commit comments