1- use rustc_ast:: InlineAsmTemplatePiece ;
1+ use rustc_ast:: { InlineAsmOptions , InlineAsmTemplatePiece } ;
22use rustc_data_structures:: fx:: FxIndexSet ;
33use rustc_hir:: { self as hir, LangItem } ;
44use rustc_middle:: bug;
@@ -124,7 +124,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
124124 idx : usize ,
125125 reg : InlineAsmRegOrRegClass ,
126126 expr : & ' tcx hir:: Expr < ' tcx > ,
127- template : & [ InlineAsmTemplatePiece ] ,
127+ asm : & hir :: InlineAsm < ' tcx > ,
128128 is_input : bool ,
129129 tied_input : Option < ( & ' tcx hir:: Expr < ' tcx > , Option < InlineAsmType > ) > ,
130130 target_features : & FxIndexSet < Symbol > ,
@@ -267,7 +267,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
267267 // Search for any use of this operand without a modifier and emit
268268 // the suggestion for them.
269269 let mut spans = vec ! [ ] ;
270- for piece in template {
270+ for piece in asm . template {
271271 if let & InlineAsmTemplatePiece :: Placeholder { operand_idx, modifier, span } = piece
272272 {
273273 if operand_idx == idx && modifier. is_none ( ) {
@@ -299,6 +299,24 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
299299 }
300300 }
301301
302+ if let ty:: RawPtr ( _, mutability) = * ty. kind ( ) {
303+ let is_mut = match mutability {
304+ hir:: Mutability :: Not => false ,
305+ hir:: Mutability :: Mut => true ,
306+ } ;
307+
308+ if is_mut && asm. options . contains ( InlineAsmOptions :: READONLY ) {
309+ let msg = "Passing a mutable pointer to asm!() with 'readonly' option" ;
310+ let note = "Mutable pointer suggest that this piece of assembly modifies the underlying object, consider using const pointer or checking the options" ;
311+ self . tcx . dcx ( ) . struct_span_warn ( expr. span , msg) . with_note ( note) . emit ( ) ;
312+ }
313+ if asm. options . contains ( InlineAsmOptions :: NOMEM ) {
314+ let msg = "Passing a pointer to asm!() with 'nomem' option" ;
315+ let note = "Pointer suggest that this piece of assembly reads the underlying object, consider using usize or checking the options" ;
316+ self . tcx . dcx ( ) . struct_span_warn ( expr. span , msg) . with_note ( note) . emit ( ) ;
317+ }
318+ }
319+
302320 Some ( asm_ty)
303321 }
304322
@@ -399,46 +417,30 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
399417
400418 match * op {
401419 hir:: InlineAsmOperand :: In { reg, expr } => {
402- self . check_asm_operand_type (
403- idx,
404- reg,
405- expr,
406- asm. template ,
407- true ,
408- None ,
409- target_features,
410- ) ;
420+ self . check_asm_operand_type ( idx, reg, expr, asm, true , None , target_features) ;
411421 }
412422 hir:: InlineAsmOperand :: Out { reg, late : _, expr } => {
413423 if let Some ( expr) = expr {
414424 self . check_asm_operand_type (
415425 idx,
416426 reg,
417427 expr,
418- asm. template ,
428+ asm,
419429 false ,
420430 None ,
421431 target_features,
422432 ) ;
423433 }
424434 }
425435 hir:: InlineAsmOperand :: InOut { reg, late : _, expr } => {
426- self . check_asm_operand_type (
427- idx,
428- reg,
429- expr,
430- asm. template ,
431- false ,
432- None ,
433- target_features,
434- ) ;
436+ self . check_asm_operand_type ( idx, reg, expr, asm, false , None , target_features) ;
435437 }
436438 hir:: InlineAsmOperand :: SplitInOut { reg, late : _, in_expr, out_expr } => {
437439 let in_ty = self . check_asm_operand_type (
438440 idx,
439441 reg,
440442 in_expr,
441- asm. template ,
443+ asm,
442444 true ,
443445 None ,
444446 target_features,
@@ -448,7 +450,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
448450 idx,
449451 reg,
450452 out_expr,
451- asm. template ,
453+ asm,
452454 false ,
453455 Some ( ( in_expr, in_ty) ) ,
454456 target_features,
0 commit comments