@@ -3,7 +3,7 @@ use std::time::Duration;
33use std:: { cmp, iter} ;
44
55use rand:: RngCore ;
6- use rustc_abi:: { Align , CanonAbi , ExternAbi , FieldIdx , FieldsShape , Size , Variants } ;
6+ use rustc_abi:: { Align , ExternAbi , FieldIdx , FieldsShape , Size , Variants } ;
77use rustc_apfloat:: Float ;
88use rustc_apfloat:: ieee:: { Double , Half , Quad , Single } ;
99use rustc_hir:: Safety ;
@@ -14,11 +14,10 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
1414use rustc_middle:: middle:: dependency_format:: Linkage ;
1515use rustc_middle:: middle:: exported_symbols:: ExportedSymbol ;
1616use rustc_middle:: ty:: layout:: { LayoutOf , MaybeResult , TyAndLayout } ;
17- use rustc_middle:: ty:: { self , Binder , FloatTy , FnSig , IntTy , Ty , TyCtxt , UintTy } ;
17+ use rustc_middle:: ty:: { self , FloatTy , IntTy , Ty , TyCtxt , UintTy } ;
1818use rustc_session:: config:: CrateType ;
1919use rustc_span:: { Span , Symbol } ;
2020use rustc_symbol_mangling:: mangle_internal_symbol;
21- use rustc_target:: callconv:: FnAbi ;
2221
2322use crate :: * ;
2423
@@ -437,7 +436,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
437436 /// For now, arguments must be scalars (so that the caller does not have to know the layout).
438437 ///
439438 /// If you do not provide a return place, a dangling zero-sized place will be created
440- /// for your convenience.
439+ /// for your convenience. This is only valid if the return type is `()`.
441440 fn call_function (
442441 & mut self ,
443442 f : ty:: Instance < ' tcx > ,
@@ -452,7 +451,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
452451 let mir = this. load_mir ( f. def , None ) ?;
453452 let dest = match dest {
454453 Some ( dest) => dest. clone ( ) ,
455- None => MPlaceTy :: fake_alloc_zst ( this. layout_of ( mir . return_ty ( ) ) ? ) ,
454+ None => MPlaceTy :: fake_alloc_zst ( this. machine . layouts . unit ) ,
456455 } ;
457456
458457 // Construct a function pointer type representing the caller perspective.
@@ -465,6 +464,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
465464 ) ;
466465 let caller_fn_abi = this. fn_abi_of_fn_ptr ( ty:: Binder :: dummy ( sig) , ty:: List :: empty ( ) ) ?;
467466
467+ // This will also show proper errors if there is any ABI mismatch.
468468 this. init_stack_frame (
469469 f,
470470 mir,
@@ -929,21 +929,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
929929 self . read_c_str_with_char_size ( ptr, wchar_t. size , wchar_t. align . abi )
930930 }
931931
932- /// Check that the calling convention is what we expect.
933- fn check_callconv < ' a > (
934- & self ,
935- fn_abi : & FnAbi < ' tcx , Ty < ' tcx > > ,
936- exp_abi : CanonAbi ,
937- ) -> InterpResult < ' a , ( ) > {
938- if fn_abi. conv != exp_abi {
939- throw_ub_format ! (
940- r#"calling a function with calling convention "{exp_abi}" using caller calling convention "{}""# ,
941- fn_abi. conv
942- ) ;
943- }
944- interp_ok ( ( ) )
945- }
946-
947932 fn frame_in_std ( & self ) -> bool {
948933 let this = self . eval_context_ref ( ) ;
949934 let frame = this. frame ( ) ;
@@ -967,161 +952,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
967952 crate_name == "std" || crate_name == "std_miri_test"
968953 }
969954
970- fn check_abi_and_shim_symbol_clash (
971- & mut self ,
972- abi : & FnAbi < ' tcx , Ty < ' tcx > > ,
973- exp_abi : CanonAbi ,
974- link_name : Symbol ,
975- ) -> InterpResult < ' tcx , ( ) > {
976- self . check_callconv ( abi, exp_abi) ?;
977- if let Some ( ( body, instance) ) = self . eval_context_mut ( ) . lookup_exported_symbol ( link_name) ? {
978- // If compiler-builtins is providing the symbol, then don't treat it as a clash.
979- // We'll use our built-in implementation in `emulate_foreign_item_inner` for increased
980- // performance. Note that this means we won't catch any undefined behavior in
981- // compiler-builtins when running other crates, but Miri can still be run on
982- // compiler-builtins itself (or any crate that uses it as a normal dependency)
983- if self . eval_context_ref ( ) . tcx . is_compiler_builtins ( instance. def_id ( ) . krate ) {
984- return interp_ok ( ( ) ) ;
985- }
986-
987- throw_machine_stop ! ( TerminationInfo :: SymbolShimClashing {
988- link_name,
989- span: body. span. data( ) ,
990- } )
991- }
992- interp_ok ( ( ) )
993- }
994-
995- fn check_shim < ' a , const N : usize > (
996- & mut self ,
997- abi : & FnAbi < ' tcx , Ty < ' tcx > > ,
998- exp_abi : CanonAbi ,
999- link_name : Symbol ,
1000- args : & ' a [ OpTy < ' tcx > ] ,
1001- ) -> InterpResult < ' tcx , & ' a [ OpTy < ' tcx > ; N ] > {
1002- self . check_abi_and_shim_symbol_clash ( abi, exp_abi, link_name) ?;
1003-
1004- if abi. c_variadic {
1005- throw_ub_format ! (
1006- "calling a non-variadic function with a variadic caller-side signature"
1007- ) ;
1008- }
1009- if let Ok ( ops) = args. try_into ( ) {
1010- return interp_ok ( ops) ;
1011- }
1012- throw_ub_format ! (
1013- "incorrect number of arguments for `{link_name}`: got {}, expected {}" ,
1014- args. len( ) ,
1015- N
1016- )
1017- }
1018-
1019- /// Check that the given `caller_fn_abi` matches the expected ABI described by
1020- /// `callee_abi`, `callee_input_tys`, `callee_output_ty`, and then returns the list of
1021- /// arguments.
1022- fn check_shim_abi < ' a , const N : usize > (
1023- & mut self ,
1024- link_name : Symbol ,
1025- caller_fn_abi : & FnAbi < ' tcx , Ty < ' tcx > > ,
1026- callee_abi : ExternAbi ,
1027- callee_input_tys : [ Ty < ' tcx > ; N ] ,
1028- callee_output_ty : Ty < ' tcx > ,
1029- caller_args : & ' a [ OpTy < ' tcx > ] ,
1030- ) -> InterpResult < ' tcx , & ' a [ OpTy < ' tcx > ; N ] > {
1031- let this = self . eval_context_mut ( ) ;
1032- let mut inputs_and_output = callee_input_tys. to_vec ( ) ;
1033- inputs_and_output. push ( callee_output_ty) ;
1034- let fn_sig_binder = Binder :: dummy ( FnSig {
1035- inputs_and_output : this. machine . tcx . mk_type_list ( & inputs_and_output) ,
1036- c_variadic : false ,
1037- // This does not matter for the ABI.
1038- safety : Safety :: Safe ,
1039- abi : callee_abi,
1040- } ) ;
1041- let callee_fn_abi = this. fn_abi_of_fn_ptr ( fn_sig_binder, Default :: default ( ) ) ?;
1042-
1043- this. check_abi_and_shim_symbol_clash ( caller_fn_abi, callee_fn_abi. conv , link_name) ?;
1044-
1045- if caller_fn_abi. c_variadic {
1046- throw_ub_format ! (
1047- "ABI mismatch: calling a non-variadic function with a variadic caller-side signature"
1048- ) ;
1049- }
1050-
1051- if callee_fn_abi. fixed_count != caller_fn_abi. fixed_count {
1052- throw_ub_format ! (
1053- "ABI mismatch: expected {} arguments, found {} arguments " ,
1054- callee_fn_abi. fixed_count,
1055- caller_fn_abi. fixed_count
1056- ) ;
1057- }
1058-
1059- if callee_fn_abi. can_unwind && !caller_fn_abi. can_unwind {
1060- throw_ub_format ! (
1061- "ABI mismatch: callee may unwind, but caller-side signature prohibits unwinding" ,
1062- ) ;
1063- }
1064-
1065- if !this. check_argument_compat ( & caller_fn_abi. ret , & callee_fn_abi. ret ) ? {
1066- throw_ub ! ( AbiMismatchReturn {
1067- caller_ty: caller_fn_abi. ret. layout. ty,
1068- callee_ty: callee_fn_abi. ret. layout. ty
1069- } ) ;
1070- }
1071-
1072- if let Some ( index) = caller_fn_abi
1073- . args
1074- . iter ( )
1075- . zip ( callee_fn_abi. args . iter ( ) )
1076- . map ( |( caller_arg, callee_arg) | this. check_argument_compat ( caller_arg, callee_arg) )
1077- . collect :: < InterpResult < ' tcx , Vec < bool > > > ( ) ?
1078- . into_iter ( )
1079- . position ( |b| !b)
1080- {
1081- throw_ub ! ( AbiMismatchArgument {
1082- caller_ty: caller_fn_abi. args[ index] . layout. ty,
1083- callee_ty: callee_fn_abi. args[ index] . layout. ty
1084- } ) ;
1085- }
1086-
1087- if let Ok ( ops) = caller_args. try_into ( ) {
1088- return interp_ok ( ops) ;
1089- }
1090- unreachable ! ( )
1091- }
1092-
1093- /// Check shim for variadic function.
1094- /// Returns a tuple that consisting of an array of fixed args, and a slice of varargs.
1095- fn check_shim_variadic < ' a , const N : usize > (
1096- & mut self ,
1097- abi : & FnAbi < ' tcx , Ty < ' tcx > > ,
1098- exp_abi : CanonAbi ,
1099- link_name : Symbol ,
1100- args : & ' a [ OpTy < ' tcx > ] ,
1101- ) -> InterpResult < ' tcx , ( & ' a [ OpTy < ' tcx > ; N ] , & ' a [ OpTy < ' tcx > ] ) >
1102- where
1103- & ' a [ OpTy < ' tcx > ; N ] : TryFrom < & ' a [ OpTy < ' tcx > ] > ,
1104- {
1105- self . check_abi_and_shim_symbol_clash ( abi, exp_abi, link_name) ?;
1106-
1107- if !abi. c_variadic {
1108- throw_ub_format ! (
1109- "calling a variadic function with a non-variadic caller-side signature"
1110- ) ;
1111- }
1112- if abi. fixed_count != u32:: try_from ( N ) . unwrap ( ) {
1113- throw_ub_format ! (
1114- "incorrect number of fixed arguments for variadic function `{}`: got {}, expected {N}" ,
1115- link_name. as_str( ) ,
1116- abi. fixed_count
1117- )
1118- }
1119- if let Some ( args) = args. split_first_chunk ( ) {
1120- return interp_ok ( args) ;
1121- }
1122- panic ! ( "mismatch between signature and `args` slice" ) ;
1123- }
1124-
1125955 /// Mark a machine allocation that was just created as immutable.
1126956 fn mark_immutable ( & mut self , mplace : & MPlaceTy < ' tcx > ) {
1127957 let this = self . eval_context_mut ( ) ;
@@ -1317,39 +1147,6 @@ impl<'tcx> MiriMachine<'tcx> {
13171147 }
13181148}
13191149
1320- /// Check that the number of args is what we expect.
1321- pub fn check_intrinsic_arg_count < ' a , ' tcx , const N : usize > (
1322- args : & ' a [ OpTy < ' tcx > ] ,
1323- ) -> InterpResult < ' tcx , & ' a [ OpTy < ' tcx > ; N ] >
1324- where
1325- & ' a [ OpTy < ' tcx > ; N ] : TryFrom < & ' a [ OpTy < ' tcx > ] > ,
1326- {
1327- if let Ok ( ops) = args. try_into ( ) {
1328- return interp_ok ( ops) ;
1329- }
1330- throw_ub_format ! (
1331- "incorrect number of arguments for intrinsic: got {}, expected {}" ,
1332- args. len( ) ,
1333- N
1334- )
1335- }
1336-
1337- /// Check that the number of varargs is at least the minimum what we expect.
1338- /// Fixed args should not be included.
1339- pub fn check_min_vararg_count < ' a , ' tcx , const N : usize > (
1340- name : & ' a str ,
1341- args : & ' a [ OpTy < ' tcx > ] ,
1342- ) -> InterpResult < ' tcx , & ' a [ OpTy < ' tcx > ; N ] > {
1343- if let Some ( ( ops, _) ) = args. split_first_chunk ( ) {
1344- return interp_ok ( ops) ;
1345- }
1346- throw_ub_format ! (
1347- "not enough variadic arguments for `{name}`: got {}, expected at least {}" ,
1348- args. len( ) ,
1349- N
1350- )
1351- }
1352-
13531150pub fn isolation_abort_error < ' tcx > ( name : & str ) -> InterpResult < ' tcx > {
13541151 throw_machine_stop ! ( TerminationInfo :: UnsupportedInIsolation ( format!(
13551152 "{name} not available when isolation is enabled" ,
0 commit comments