@@ -26,12 +26,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
2626 dest : & MPlaceTy < ' tcx , Provenance > ,
2727 ret : Option < mir:: BasicBlock > ,
2828 _unwind : mir:: UnwindAction ,
29- ) -> InterpResult < ' tcx > {
29+ ) -> InterpResult < ' tcx , Option < ty :: Instance < ' tcx > > > {
3030 let this = self . eval_context_mut ( ) ;
3131
3232 // See if the core engine can handle this intrinsic.
3333 if this. emulate_intrinsic ( instance, args, dest, ret) ? {
34- return Ok ( ( ) ) ;
34+ return Ok ( None ) ;
3535 }
3636 let intrinsic_name = this. tcx . item_name ( instance. def_id ( ) ) ;
3737 let intrinsic_name = intrinsic_name. as_str ( ) ;
@@ -54,16 +54,27 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
5454
5555 // Some intrinsics are special and need the "ret".
5656 match intrinsic_name {
57- "catch_unwind" => return this. handle_catch_unwind ( args, dest, ret) ,
57+ "catch_unwind" => {
58+ this. handle_catch_unwind ( args, dest, ret) ?;
59+ return Ok ( None ) ;
60+ }
5861 _ => { }
5962 }
6063
6164 // The rest jumps to `ret` immediately.
62- this. emulate_intrinsic_by_name ( intrinsic_name, instance. args , args, dest) ?;
65+ if !this. emulate_intrinsic_by_name ( intrinsic_name, instance. args , args, dest) ? {
66+ if this. tcx . intrinsic ( instance. def_id ( ) ) . unwrap ( ) . must_be_overridden {
67+ throw_unsup_format ! ( "unimplemented intrinsic: `{intrinsic_name}`" )
68+ }
69+ return Ok ( Some ( ty:: Instance {
70+ def : ty:: InstanceDef :: Item ( instance. def_id ( ) ) ,
71+ args : instance. args ,
72+ } ) )
73+ }
6374
6475 trace ! ( "{:?}" , this. dump_place( & dest. clone( ) . into( ) ) ) ;
6576 this. go_to_block ( ret) ;
66- Ok ( ( ) )
77+ Ok ( None )
6778 }
6879
6980 /// Emulates a Miri-supported intrinsic (not supported by the core engine).
@@ -73,7 +84,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
7384 generic_args : ty:: GenericArgsRef < ' tcx > ,
7485 args : & [ OpTy < ' tcx , Provenance > ] ,
7586 dest : & MPlaceTy < ' tcx , Provenance > ,
76- ) -> InterpResult < ' tcx > {
87+ ) -> InterpResult < ' tcx , bool > {
7788 let this = self . eval_context_mut ( ) ;
7889
7990 if let Some ( name) = intrinsic_name. strip_prefix ( "atomic_" ) {
@@ -84,24 +95,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
8495 }
8596
8697 match intrinsic_name {
87- // Miri overwriting CTFE intrinsics.
88- "ptr_guaranteed_cmp" => {
89- let [ left, right] = check_arg_count ( args) ?;
90- let left = this. read_immediate ( left) ?;
91- let right = this. read_immediate ( right) ?;
92- let val = this. wrapping_binary_op ( mir:: BinOp :: Eq , & left, & right) ?;
93- // We're type punning a bool as an u8 here.
94- this. write_scalar ( val. to_scalar ( ) , dest) ?;
95- }
96- "const_allocate" => {
97- // For now, for compatibility with the run-time implementation of this, we just return null.
98- // See <https://github.com/rust-lang/rust/issues/93935>.
99- this. write_null ( dest) ?;
100- }
101- "const_deallocate" => {
102- // complete NOP
103- }
104-
10598 // Raw memory accesses
10699 "volatile_load" => {
107100 let [ place] = check_arg_count ( args) ?;
@@ -425,9 +418,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
425418 throw_machine_stop ! ( TerminationInfo :: Abort ( format!( "trace/breakpoint trap" ) ) )
426419 }
427420
428- name => throw_unsup_format ! ( "unimplemented intrinsic: `{name}`" ) ,
421+ _ => return Ok ( false ) ,
429422 }
430423
431- Ok ( ( ) )
424+ Ok ( true )
432425 }
433426}
0 commit comments