@@ -24,7 +24,7 @@ use rustc_middle::ty::{Const, TyCtxt};
24
24
use rustc_smir:: rustc_internal;
25
25
use stable_mir:: CrateDef ;
26
26
use stable_mir:: abi:: { FieldsShape , Scalar , TagEncoding , ValueAbi , VariantsShape , WrappingRange } ;
27
- use stable_mir:: mir:: mono:: { Instance , InstanceKind } ;
27
+ use stable_mir:: mir:: mono:: Instance ;
28
28
use stable_mir:: mir:: visit:: { Location , PlaceContext , PlaceRef } ;
29
29
use stable_mir:: mir:: {
30
30
AggregateKind , BasicBlockIdx , BinOp , Body , CastKind , ConstOperand , FieldIdx , Local , LocalDecl ,
@@ -385,50 +385,47 @@ impl MirVisitor for CheckValueVisitor<'_, '_> {
385
385
// Note: For transmute, both Src and Dst must be valid type.
386
386
// In this case, we need to save the Dst, and invoke super_terminator.
387
387
self . super_terminator ( term, location) ;
388
- let instance = expect_instance ( self . locals , func) ;
389
- if instance. kind == InstanceKind :: Intrinsic {
390
- match instance. intrinsic_name ( ) . unwrap ( ) . as_str ( ) {
391
- "write_bytes" => {
392
- // The write bytes intrinsic may trigger UB in safe code.
393
- // pub unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize)
394
- // <https://doc.rust-lang.org/stable/core/intrinsics/fn.write_bytes.html>
395
- // This is an over-approximation since writing an invalid value is
396
- // not UB, only reading it will be.
397
- assert_eq ! (
398
- args. len( ) ,
399
- 3 ,
400
- "Unexpected number of arguments for `write_bytes`"
401
- ) ;
402
- let TyKind :: RigidTy ( RigidTy :: RawPtr ( target_ty, Mutability :: Mut ) ) =
403
- args[ 0 ] . ty ( self . locals ) . unwrap ( ) . kind ( )
404
- else {
405
- unreachable ! ( )
406
- } ;
407
- let validity = ty_validity_per_offset ( & self . machine , target_ty, 0 ) ;
408
- match validity {
409
- Ok ( ranges) if ranges. is_empty ( ) => { }
410
- Ok ( ranges) => {
411
- let sz = rustc_internal:: stable ( Const :: from_target_usize (
412
- self . tcx ,
413
- target_ty. layout ( ) . unwrap ( ) . shape ( ) . size . bytes ( ) as u64 ,
414
- ) ) ;
415
- self . push_target ( SourceOp :: BytesValidity {
416
- target_ty,
417
- rvalue : Rvalue :: Repeat ( args[ 1 ] . clone ( ) , sz) ,
418
- ranges,
419
- } )
420
- }
421
- _ => self . push_target ( SourceOp :: UnsupportedCheck {
422
- check : "write_bytes" . to_string ( ) ,
423
- ty : target_ty,
424
- } ) ,
388
+ match intrinsic_name ( self . locals , func) . as_deref ( ) {
389
+ Some ( "write_bytes" ) => {
390
+ // The write bytes intrinsic may trigger UB in safe code.
391
+ // pub unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize)
392
+ // <https://doc.rust-lang.org/stable/core/intrinsics/fn.write_bytes.html>
393
+ // This is an over-approximation since writing an invalid value is
394
+ // not UB, only reading it will be.
395
+ assert_eq ! (
396
+ args. len( ) ,
397
+ 3 ,
398
+ "Unexpected number of arguments for `write_bytes`"
399
+ ) ;
400
+ let TyKind :: RigidTy ( RigidTy :: RawPtr ( target_ty, Mutability :: Mut ) ) =
401
+ args[ 0 ] . ty ( self . locals ) . unwrap ( ) . kind ( )
402
+ else {
403
+ unreachable ! ( )
404
+ } ;
405
+ let validity = ty_validity_per_offset ( & self . machine , target_ty, 0 ) ;
406
+ match validity {
407
+ Ok ( ranges) if ranges. is_empty ( ) => { }
408
+ Ok ( ranges) => {
409
+ let sz = rustc_internal:: stable ( Const :: from_target_usize (
410
+ self . tcx ,
411
+ target_ty. layout ( ) . unwrap ( ) . shape ( ) . size . bytes ( ) as u64 ,
412
+ ) ) ;
413
+ self . push_target ( SourceOp :: BytesValidity {
414
+ target_ty,
415
+ rvalue : Rvalue :: Repeat ( args[ 1 ] . clone ( ) , sz) ,
416
+ ranges,
417
+ } )
425
418
}
419
+ _ => self . push_target ( SourceOp :: UnsupportedCheck {
420
+ check : "write_bytes" . to_string ( ) ,
421
+ ty : target_ty,
422
+ } ) ,
426
423
}
427
- "transmute" | "transmute_copy" => {
428
- unreachable ! ( "Should've been lowered" )
429
- }
430
- _ => { }
431
424
}
425
+ Some ( "transmute" ) | Some ( "transmute_copy" ) => {
426
+ unreachable ! ( "Should've been lowered" )
427
+ }
428
+ _ => { }
432
429
}
433
430
}
434
431
TerminatorKind :: Goto { .. }
@@ -741,16 +738,13 @@ fn assignment_check_points(
741
738
invalid_ranges
742
739
}
743
740
744
- /// Retrieve instance for the given function operand.
741
+ /// Retrieve the name of the intrinsic if this operand is an intrinsic .
745
742
///
746
- /// This will panic if the operand is not a function or if it cannot be resolved .
747
- fn expect_instance ( locals : & [ LocalDecl ] , func : & Operand ) -> Instance {
743
+ /// Intrinsics can only be invoked directly, so we can safely ignore other operand types .
744
+ fn intrinsic_name ( locals : & [ LocalDecl ] , func : & Operand ) -> Option < String > {
748
745
let ty = func. ty ( locals) . unwrap ( ) ;
749
- match ty. kind ( ) {
750
- TyKind :: RigidTy ( RigidTy :: FnDef ( def, args) ) => Instance :: resolve ( def, & args) . unwrap ( ) ,
751
- TyKind :: RigidTy ( RigidTy :: FnPtr ( sig) ) => todo ! ( "Add support to FnPtr: {sig:?}" ) ,
752
- _ => unreachable ! ( "Found: {func:?}" ) ,
753
- }
746
+ let TyKind :: RigidTy ( RigidTy :: FnDef ( def, args) ) = ty. kind ( ) else { return None } ;
747
+ Instance :: resolve ( def, & args) . unwrap ( ) . intrinsic_name ( )
754
748
}
755
749
756
750
/// Instrument MIR to check the value pointed by `rvalue_ptr` satisfies requirement `req`.
0 commit comments