1
- use rustc_hir:: * ;
1
+ use clippy_utils:: diagnostics:: span_lint;
2
+ use rustc_ast:: InlineAsmOptions ;
3
+ use rustc_hir:: { Expr , ExprKind , InlineAsm , InlineAsmOperand } ;
2
4
use rustc_lint:: { LateContext , LateLintPass } ;
3
5
use rustc_session:: declare_lint_pass;
4
- use rustc_ast:: InlineAsmOptions ;
5
- use clippy_utils:: diagnostics:: span_lint_and_then;
6
- use rustc_span:: { BytePos , Span } ;
7
- use rustc_errors:: Applicability ;
6
+ use rustc_span:: Span ;
8
7
9
8
fn has_in_operand_pointer ( cx : & LateContext < ' _ > , asm_op : & InlineAsmOperand < ' _ > ) -> bool {
10
9
let asm_in_expr = match asm_op {
@@ -15,43 +14,37 @@ fn has_in_operand_pointer(cx: &LateContext<'_>, asm_op: &InlineAsmOperand<'_>) -
15
14
| InlineAsmOperand :: Label { .. } => return false ,
16
15
InlineAsmOperand :: In { expr, .. } => expr,
17
16
InlineAsmOperand :: InOut { expr, .. } => expr,
18
- InlineAsmOperand :: SplitInOut { in_expr, ..} => in_expr,
17
+ InlineAsmOperand :: SplitInOut { in_expr, .. } => in_expr,
19
18
} ;
20
19
21
- return match cx. typeck_results ( ) . expr_ty ( asm_in_expr) . kind ( ) {
22
- rustc_middle:: ty:: TyKind :: RawPtr ( ..) => true ,
23
- rustc_middle:: ty:: TyKind :: Ref ( ..) => true ,
24
- _ => false ,
25
- } ;
20
+ // This checks for raw ptrs, refs and function pointers - the last one
21
+ // also technically counts as reading memory.
22
+ return cx. typeck_results ( ) . expr_ty ( asm_in_expr) . is_any_ptr ( ) ;
26
23
}
27
24
28
- fn shift_span_by_two_bytes ( s : Span ) -> Span {
29
- s. with_lo ( s. lo ( ) + BytePos ( 2 ) )
30
- }
31
-
32
- fn yeet_lint ( cx : & LateContext < ' _ > , asm : & InlineAsm < ' _ > , asm_span : Span , op_spans : Vec < Span > ) {
33
- let last_op_span = asm. operands . last ( ) . unwrap ( ) . 1 ;
34
- let probably_asm_options_span = asm_span. trim_start ( last_op_span) . map ( shift_span_by_two_bytes) ;
35
-
36
- span_lint_and_then ( cx, POINTER_IN_NOMEM_ASM_BLOCK , op_spans, "passing pointer to nomem asm block" , |diag| {
37
- if let Some ( probably_asm_options_span) = probably_asm_options_span {
38
- diag. span_note ( probably_asm_options_span, "flags declared here" ) ;
39
- }
40
- } ) ;
25
+ fn yeet_lint ( cx : & LateContext < ' _ > , op_spans : Vec < Span > ) {
26
+ span_lint (
27
+ cx,
28
+ POINTER_IN_NOMEM_ASM_BLOCK ,
29
+ op_spans,
30
+ "passing pointer to nomem asm block" ,
31
+ ) ;
41
32
}
42
33
43
- fn check_asm ( cx : & LateContext < ' _ > , asm : & InlineAsm < ' _ > , asm_span : Span ) {
44
- if !asm. options . contains ( InlineAsmOptions :: NOMEM ) || asm . operands . is_empty ( ) {
34
+ fn check_asm ( cx : & LateContext < ' _ > , asm : & InlineAsm < ' _ > ) {
35
+ if !asm. options . contains ( InlineAsmOptions :: NOMEM ) {
45
36
return ;
46
37
}
47
38
48
- let spans = asm. operands . iter ( )
39
+ let spans = asm
40
+ . operands
41
+ . iter ( )
49
42
. filter ( |( op, _span) | has_in_operand_pointer ( cx, op) )
50
43
. map ( |( _op, span) | * span)
51
44
. collect :: < Vec < Span > > ( ) ;
52
45
53
46
if !spans. is_empty ( ) {
54
- yeet_lint ( cx, asm , asm_span , spans) ;
47
+ yeet_lint ( cx, spans) ;
55
48
}
56
49
}
57
50
@@ -86,7 +79,7 @@ declare_lint_pass!(PointerInNomemAsmBlock => [POINTER_IN_NOMEM_ASM_BLOCK]);
86
79
impl < ' tcx > LateLintPass < ' tcx > for PointerInNomemAsmBlock {
87
80
fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & Expr < ' tcx > ) {
88
81
if let ExprKind :: InlineAsm ( asm) = & expr. kind {
89
- check_asm ( cx, asm, expr . span ) ;
82
+ check_asm ( cx, asm) ;
90
83
}
91
84
}
92
85
}
0 commit comments