1- use rustc_hir:: * ;
1+ use clippy_utils:: diagnostics:: span_lint;
2+ use rustc_ast:: InlineAsmOptions ;
3+ use rustc_hir:: { Expr , ExprKind , InlineAsm , InlineAsmOperand } ;
24use rustc_lint:: { LateContext , LateLintPass } ;
35use 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 ;
87
98fn has_in_operand_pointer ( cx : & LateContext < ' _ > , asm_op : & InlineAsmOperand < ' _ > ) -> bool {
109 let asm_in_expr = match asm_op {
@@ -15,43 +14,37 @@ fn has_in_operand_pointer(cx: &LateContext<'_>, asm_op: &InlineAsmOperand<'_>) -
1514 | InlineAsmOperand :: Label { .. } => return false ,
1615 InlineAsmOperand :: In { expr, .. } => expr,
1716 InlineAsmOperand :: InOut { expr, .. } => expr,
18- InlineAsmOperand :: SplitInOut { in_expr, ..} => in_expr,
17+ InlineAsmOperand :: SplitInOut { in_expr, .. } => in_expr,
1918 } ;
2019
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 ( ) ;
2623}
2724
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+ ) ;
4132}
4233
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 ) {
4536 return ;
4637 }
4738
48- let spans = asm. operands . iter ( )
39+ let spans = asm
40+ . operands
41+ . iter ( )
4942 . filter ( |( op, _span) | has_in_operand_pointer ( cx, op) )
5043 . map ( |( _op, span) | * span)
5144 . collect :: < Vec < Span > > ( ) ;
5245
5346 if !spans. is_empty ( ) {
54- yeet_lint ( cx, asm , asm_span , spans) ;
47+ yeet_lint ( cx, spans) ;
5548 }
5649}
5750
@@ -86,7 +79,7 @@ declare_lint_pass!(PointerInNomemAsmBlock => [POINTER_IN_NOMEM_ASM_BLOCK]);
8679impl < ' tcx > LateLintPass < ' tcx > for PointerInNomemAsmBlock {
8780 fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & Expr < ' tcx > ) {
8881 if let ExprKind :: InlineAsm ( asm) = & expr. kind {
89- check_asm ( cx, asm, expr . span ) ;
82+ check_asm ( cx, asm) ;
9083 }
9184 }
9285}
0 commit comments