1
1
//! Checks validity of naked functions.
2
2
3
3
use rustc_ast:: { Attribute , InlineAsmOptions } ;
4
+ use rustc_errors:: struct_span_err;
4
5
use rustc_hir as hir;
5
6
use rustc_hir:: def_id:: LocalDefId ;
6
7
use rustc_hir:: intravisit:: { FnKind , Visitor } ;
7
8
use rustc_hir:: { ExprKind , HirId , InlineAsmOperand , StmtKind } ;
8
9
use rustc_middle:: ty:: query:: Providers ;
9
10
use rustc_middle:: ty:: TyCtxt ;
10
11
use rustc_session:: lint:: builtin:: UNDEFINED_NAKED_FUNCTION_ABI ;
11
- use rustc_session:: lint:: builtin:: UNSUPPORTED_NAKED_FUNCTIONS ;
12
12
use rustc_span:: symbol:: sym;
13
13
use rustc_span:: Span ;
14
14
use rustc_target:: spec:: abi:: Abi ;
@@ -64,18 +64,16 @@ impl<'tcx> Visitor<'tcx> for CheckNakedFunctions<'tcx> {
64
64
check_abi ( self . tcx , hir_id, fn_header. abi , ident_span) ;
65
65
check_no_patterns ( self . tcx , body. params ) ;
66
66
check_no_parameters_use ( self . tcx , body) ;
67
- check_asm ( self . tcx , hir_id , body, span) ;
68
- check_inline ( self . tcx , hir_id , attrs) ;
67
+ check_asm ( self . tcx , body, span) ;
68
+ check_inline ( self . tcx , attrs) ;
69
69
}
70
70
}
71
71
}
72
72
73
73
/// Check that the function isn't inlined.
74
- fn check_inline ( tcx : TyCtxt < ' _ > , hir_id : HirId , attrs : & [ Attribute ] ) {
74
+ fn check_inline ( tcx : TyCtxt < ' _ > , attrs : & [ Attribute ] ) {
75
75
for attr in attrs. iter ( ) . filter ( |attr| attr. has_name ( sym:: inline) ) {
76
- tcx. struct_span_lint_hir ( UNSUPPORTED_NAKED_FUNCTIONS , hir_id, attr. span , |lint| {
77
- lint. build ( "naked functions cannot be inlined" ) . emit ( ) ;
78
- } ) ;
76
+ tcx. sess . struct_span_err ( attr. span , "naked functions cannot be inlined" ) . emit ( ) ;
79
77
}
80
78
}
81
79
@@ -146,31 +144,31 @@ impl<'tcx> Visitor<'tcx> for CheckParameters<'tcx> {
146
144
}
147
145
148
146
/// Checks that function body contains a single inline assembly block.
149
- fn check_asm < ' tcx > ( tcx : TyCtxt < ' tcx > , hir_id : HirId , body : & ' tcx hir:: Body < ' tcx > , fn_span : Span ) {
147
+ fn check_asm < ' tcx > ( tcx : TyCtxt < ' tcx > , body : & ' tcx hir:: Body < ' tcx > , fn_span : Span ) {
150
148
let mut this = CheckInlineAssembly { tcx, items : Vec :: new ( ) } ;
151
149
this. visit_body ( body) ;
152
150
if let [ ( ItemKind :: Asm , _) ] = this. items [ ..] {
153
151
// Ok.
154
152
} else {
155
- tcx . struct_span_lint_hir ( UNSUPPORTED_NAKED_FUNCTIONS , hir_id , fn_span , |lint| {
156
- let mut diag = lint . build ( "naked functions must contain a single asm block" ) ;
157
- let mut has_asm = false ;
158
- for & ( kind , span ) in & this . items {
159
- match kind {
160
- ItemKind :: Asm if has_asm => {
161
- diag . span_label (
162
- span ,
163
- "multiple asm blocks are unsupported in naked functions" ,
164
- ) ;
165
- }
166
- ItemKind :: Asm => has_asm = true ,
167
- ItemKind :: NonAsm => {
168
- diag . span_label ( span , "non-asm is unsupported in naked functions" ) ;
169
- }
153
+ let mut diag = struct_span_err ! (
154
+ tcx . sess ,
155
+ fn_span ,
156
+ E0787 ,
157
+ "naked functions must contain a single asm block"
158
+ ) ;
159
+ let mut has_asm = false ;
160
+ for & ( kind , span ) in & this . items {
161
+ match kind {
162
+ ItemKind :: Asm if has_asm => {
163
+ diag . span_label ( span , "multiple asm blocks are unsupported in naked functions" ) ;
164
+ }
165
+ ItemKind :: Asm => has_asm = true ,
166
+ ItemKind :: NonAsm => {
167
+ diag . span_label ( span , "non-asm is unsupported in naked functions" ) ;
170
168
}
171
169
}
172
- diag . emit ( ) ;
173
- } ) ;
170
+ }
171
+ diag . emit ( ) ;
174
172
}
175
173
}
176
174
@@ -221,7 +219,7 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
221
219
222
220
ExprKind :: InlineAsm ( ref asm) => {
223
221
self . items . push ( ( ItemKind :: Asm , span) ) ;
224
- self . check_inline_asm ( expr . hir_id , asm, span) ;
222
+ self . check_inline_asm ( asm, span) ;
225
223
}
226
224
227
225
ExprKind :: DropTemps ( ..) | ExprKind :: Block ( ..) | ExprKind :: Err => {
@@ -230,7 +228,7 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
230
228
}
231
229
}
232
230
233
- fn check_inline_asm ( & self , hir_id : HirId , asm : & ' tcx hir:: InlineAsm < ' tcx > , span : Span ) {
231
+ fn check_inline_asm ( & self , asm : & ' tcx hir:: InlineAsm < ' tcx > , span : Span ) {
234
232
let unsupported_operands: Vec < Span > = asm
235
233
. operands
236
234
. iter ( )
@@ -243,18 +241,17 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
243
241
} )
244
242
. collect ( ) ;
245
243
if !unsupported_operands. is_empty ( ) {
246
- self . tcx . struct_span_lint_hir (
247
- UNSUPPORTED_NAKED_FUNCTIONS ,
248
- hir_id,
244
+ struct_span_err ! (
245
+ self . tcx. sess,
249
246
unsupported_operands,
250
- |lint| {
251
- lint. build ( "only `const` and `sym` operands are supported in naked functions" )
252
- . emit ( ) ;
253
- } ,
254
- ) ;
247
+ E0787 ,
248
+ "only `const` and `sym` operands are supported in naked functions" ,
249
+ )
250
+ . emit ( ) ;
255
251
}
256
252
257
253
let unsupported_options: Vec < & ' static str > = [
254
+ ( InlineAsmOptions :: MAY_UNWIND , "`may_unwind`" ) ,
258
255
( InlineAsmOptions :: NOMEM , "`nomem`" ) ,
259
256
( InlineAsmOptions :: NOSTACK , "`nostack`" ) ,
260
257
( InlineAsmOptions :: PRESERVES_FLAGS , "`preserves_flags`" ) ,
@@ -266,19 +263,24 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
266
263
. collect ( ) ;
267
264
268
265
if !unsupported_options. is_empty ( ) {
269
- self . tcx . struct_span_lint_hir ( UNSUPPORTED_NAKED_FUNCTIONS , hir_id, span, |lint| {
270
- lint. build ( & format ! (
271
- "asm options unsupported in naked functions: {}" ,
272
- unsupported_options. join( ", " )
273
- ) )
274
- . emit ( ) ;
275
- } ) ;
266
+ struct_span_err ! (
267
+ self . tcx. sess,
268
+ span,
269
+ E0787 ,
270
+ "asm options unsupported in naked functions: {}" ,
271
+ unsupported_options. join( ", " )
272
+ )
273
+ . emit ( ) ;
276
274
}
277
275
278
276
if !asm. options . contains ( InlineAsmOptions :: NORETURN ) {
279
- self . tcx . struct_span_lint_hir ( UNSUPPORTED_NAKED_FUNCTIONS , hir_id, span, |lint| {
280
- lint. build ( "asm in naked functions must use `noreturn` option" ) . emit ( ) ;
281
- } ) ;
277
+ struct_span_err ! (
278
+ self . tcx. sess,
279
+ span,
280
+ E0787 ,
281
+ "asm in naked functions must use `noreturn` option"
282
+ )
283
+ . emit ( ) ;
282
284
}
283
285
}
284
286
}
0 commit comments