@@ -3,7 +3,7 @@ use std::time::Duration;
3
3
use std:: { cmp, iter} ;
4
4
5
5
use rand:: RngCore ;
6
- use rustc_abi:: { Align , CanonAbi , ExternAbi , FieldIdx , FieldsShape , Size , Variants } ;
6
+ use rustc_abi:: { Align , ExternAbi , FieldIdx , FieldsShape , Size , Variants } ;
7
7
use rustc_apfloat:: Float ;
8
8
use rustc_apfloat:: ieee:: { Double , Half , Quad , Single } ;
9
9
use rustc_hir:: Safety ;
@@ -14,11 +14,10 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
14
14
use rustc_middle:: middle:: dependency_format:: Linkage ;
15
15
use rustc_middle:: middle:: exported_symbols:: ExportedSymbol ;
16
16
use 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 } ;
18
18
use rustc_session:: config:: CrateType ;
19
19
use rustc_span:: { Span , Symbol } ;
20
20
use rustc_symbol_mangling:: mangle_internal_symbol;
21
- use rustc_target:: callconv:: FnAbi ;
22
21
23
22
use crate :: * ;
24
23
@@ -437,7 +436,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
437
436
/// For now, arguments must be scalars (so that the caller does not have to know the layout).
438
437
///
439
438
/// 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 `()`.
441
440
fn call_function (
442
441
& mut self ,
443
442
f : ty:: Instance < ' tcx > ,
@@ -452,7 +451,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
452
451
let mir = this. load_mir ( f. def , None ) ?;
453
452
let dest = match dest {
454
453
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 ) ,
456
455
} ;
457
456
458
457
// Construct a function pointer type representing the caller perspective.
@@ -465,6 +464,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
465
464
) ;
466
465
let caller_fn_abi = this. fn_abi_of_fn_ptr ( ty:: Binder :: dummy ( sig) , ty:: List :: empty ( ) ) ?;
467
466
467
+ // This will also show proper errors if there is any ABI mismatch.
468
468
this. init_stack_frame (
469
469
f,
470
470
mir,
@@ -929,21 +929,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
929
929
self . read_c_str_with_char_size ( ptr, wchar_t. size , wchar_t. align . abi )
930
930
}
931
931
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
-
947
932
fn frame_in_std ( & self ) -> bool {
948
933
let this = self . eval_context_ref ( ) ;
949
934
let frame = this. frame ( ) ;
@@ -967,161 +952,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
967
952
crate_name == "std" || crate_name == "std_miri_test"
968
953
}
969
954
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
-
1125
955
/// Mark a machine allocation that was just created as immutable.
1126
956
fn mark_immutable ( & mut self , mplace : & MPlaceTy < ' tcx > ) {
1127
957
let this = self . eval_context_mut ( ) ;
@@ -1317,39 +1147,6 @@ impl<'tcx> MiriMachine<'tcx> {
1317
1147
}
1318
1148
}
1319
1149
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
-
1353
1150
pub fn isolation_abort_error < ' tcx > ( name : & str ) -> InterpResult < ' tcx > {
1354
1151
throw_machine_stop ! ( TerminationInfo :: UnsupportedInIsolation ( format!(
1355
1152
"{name} not available when isolation is enabled" ,
0 commit comments