@@ -10,11 +10,11 @@ use rustc_middle::query::Providers;
10
10
use rustc_middle:: ty:: TyCtxt ;
11
11
use rustc_session:: lint:: builtin:: UNDEFINED_NAKED_FUNCTION_ABI ;
12
12
use rustc_span:: symbol:: sym;
13
- use rustc_span:: Span ;
13
+ use rustc_span:: { BytePos , Span } ;
14
14
use rustc_target:: spec:: abi:: Abi ;
15
15
16
16
use crate :: errors:: {
17
- NakedFunctionsAsmBlock , NakedFunctionsAsmOptions , NakedFunctionsMustUseNoreturn ,
17
+ NakedFunctionsAsmBlock , NakedFunctionsAsmOptions , NakedFunctionsMustNakedAsm ,
18
18
NakedFunctionsOperands , NoPatterns , ParamsNotAllowed , UndefinedNakedFunctionAbi ,
19
19
} ;
20
20
@@ -29,8 +29,7 @@ fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
29
29
continue ;
30
30
}
31
31
32
- let naked = tcx. has_attr ( def_id, sym:: naked) ;
33
- if !naked {
32
+ if !tcx. has_attr ( def_id, sym:: naked) {
34
33
continue ;
35
34
}
36
35
@@ -117,21 +116,29 @@ impl<'tcx> Visitor<'tcx> for CheckParameters<'tcx> {
117
116
fn check_asm < ' tcx > ( tcx : TyCtxt < ' tcx > , def_id : LocalDefId , body : & ' tcx hir:: Body < ' tcx > ) {
118
117
let mut this = CheckInlineAssembly { tcx, items : Vec :: new ( ) } ;
119
118
this. visit_body ( body) ;
120
- if let [ ( ItemKind :: Asm | ItemKind :: Err , _) ] = this. items [ ..] {
119
+ if let [ ( ItemKind :: NakedAsm | ItemKind :: Err , _) ] = this. items [ ..] {
121
120
// Ok.
122
121
} else {
123
122
let mut must_show_error = false ;
124
- let mut has_asm = false ;
123
+ let mut has_naked_asm = false ;
125
124
let mut has_err = false ;
126
125
let mut multiple_asms = vec ! [ ] ;
127
126
let mut non_asms = vec ! [ ] ;
128
127
for & ( kind, span) in & this. items {
129
128
match kind {
130
- ItemKind :: Asm if has_asm => {
129
+ ItemKind :: NakedAsm if has_naked_asm => {
131
130
must_show_error = true ;
132
131
multiple_asms. push ( span) ;
133
132
}
134
- ItemKind :: Asm => has_asm = true ,
133
+ ItemKind :: NakedAsm => has_naked_asm = true ,
134
+ ItemKind :: InlineAsm => {
135
+ has_err = true ;
136
+
137
+ // the span that contains the `asm!` call,
138
+ // so tooling can replace it with `naked_asm!`
139
+ let macro_span = span. with_hi ( span. lo ( ) + BytePos ( "asm!" . len ( ) as u32 ) ) ;
140
+ tcx. dcx ( ) . emit_err ( NakedFunctionsMustNakedAsm { span, macro_span } ) ;
141
+ }
135
142
ItemKind :: NonAsm => {
136
143
must_show_error = true ;
137
144
non_asms. push ( span) ;
@@ -160,7 +167,8 @@ struct CheckInlineAssembly<'tcx> {
160
167
161
168
#[ derive( Copy , Clone ) ]
162
169
enum ItemKind {
163
- Asm ,
170
+ NakedAsm ,
171
+ InlineAsm ,
164
172
NonAsm ,
165
173
Err ,
166
174
}
@@ -201,8 +209,18 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
201
209
}
202
210
203
211
ExprKind :: InlineAsm ( asm) => {
204
- self . items . push ( ( ItemKind :: Asm , span) ) ;
205
- self . check_inline_asm ( asm, span) ;
212
+ match asm. asm_macro {
213
+ rustc_ast:: AsmMacro :: Asm => {
214
+ self . items . push ( ( ItemKind :: InlineAsm , span) ) ;
215
+ }
216
+ rustc_ast:: AsmMacro :: NakedAsm => {
217
+ self . items . push ( ( ItemKind :: NakedAsm , span) ) ;
218
+ self . check_inline_asm ( asm, span) ;
219
+ }
220
+ rustc_ast:: AsmMacro :: GlobalAsm => {
221
+ // not allowed in this position
222
+ }
223
+ }
206
224
}
207
225
208
226
ExprKind :: DropTemps ( ..) | ExprKind :: Block ( ..) => {
@@ -246,16 +264,6 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
246
264
. join ( ", " ) ,
247
265
} ) ;
248
266
}
249
-
250
- if !asm. options . contains ( InlineAsmOptions :: NORETURN ) {
251
- let last_span = asm
252
- . operands
253
- . last ( )
254
- . map_or_else ( || asm. template_strs . last ( ) . unwrap ( ) . 2 , |op| op. 1 )
255
- . shrink_to_hi ( ) ;
256
-
257
- self . tcx . dcx ( ) . emit_err ( NakedFunctionsMustUseNoreturn { span, last_span } ) ;
258
- }
259
267
}
260
268
}
261
269
0 commit comments