@@ -26,12 +26,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
26
26
dest : & MPlaceTy < ' tcx , Provenance > ,
27
27
ret : Option < mir:: BasicBlock > ,
28
28
_unwind : mir:: UnwindAction ,
29
- ) -> InterpResult < ' tcx > {
29
+ ) -> InterpResult < ' tcx , Option < ty :: Instance < ' tcx > > > {
30
30
let this = self . eval_context_mut ( ) ;
31
31
32
32
// See if the core engine can handle this intrinsic.
33
33
if this. emulate_intrinsic ( instance, args, dest, ret) ? {
34
- return Ok ( ( ) ) ;
34
+ return Ok ( None ) ;
35
35
}
36
36
let intrinsic_name = this. tcx . item_name ( instance. def_id ( ) ) ;
37
37
let intrinsic_name = intrinsic_name. as_str ( ) ;
@@ -54,16 +54,27 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
54
54
55
55
// Some intrinsics are special and need the "ret".
56
56
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
+ }
58
61
_ => { }
59
62
}
60
63
61
64
// 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
+ }
63
74
64
75
trace ! ( "{:?}" , this. dump_place( & dest. clone( ) . into( ) ) ) ;
65
76
this. go_to_block ( ret) ;
66
- Ok ( ( ) )
77
+ Ok ( None )
67
78
}
68
79
69
80
/// 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> {
73
84
generic_args : ty:: GenericArgsRef < ' tcx > ,
74
85
args : & [ OpTy < ' tcx , Provenance > ] ,
75
86
dest : & MPlaceTy < ' tcx , Provenance > ,
76
- ) -> InterpResult < ' tcx > {
87
+ ) -> InterpResult < ' tcx , bool > {
77
88
let this = self . eval_context_mut ( ) ;
78
89
79
90
if let Some ( name) = intrinsic_name. strip_prefix ( "atomic_" ) {
@@ -84,24 +95,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
84
95
}
85
96
86
97
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
-
105
98
// Raw memory accesses
106
99
"volatile_load" => {
107
100
let [ place] = check_arg_count ( args) ?;
@@ -425,9 +418,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
425
418
throw_machine_stop ! ( TerminationInfo :: Abort ( format!( "trace/breakpoint trap" ) ) )
426
419
}
427
420
428
- name => throw_unsup_format ! ( "unimplemented intrinsic: `{name}`" ) ,
421
+ _ => return Ok ( false ) ,
429
422
}
430
423
431
- Ok ( ( ) )
424
+ Ok ( true )
432
425
}
433
426
}
0 commit comments