@@ -90,7 +90,16 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
9090 ty:: TyFnPtr ( bare_fn_ty) => {
9191 let fn_ptr = self . eval_operand_to_primval ( func) ?. to_ptr ( ) ;
9292 let ( def_id, substs, abi, sig) = self . memory . get_fn ( fn_ptr. alloc_id ) ?;
93- if abi != bare_fn_ty. abi || sig != bare_fn_ty. sig . skip_binder ( ) {
93+ let bare_sig = self . tcx . erase_late_bound_regions_and_normalize ( & bare_fn_ty. sig ) ;
94+ let bare_sig = self . tcx . erase_regions ( & bare_sig) ;
95+ // transmuting function pointers in miri is fine as long as the number of
96+ // arguments and the abi don't change.
97+ // FIXME: also check the size of the arguments' type and the return type
98+ // Didn't get it to work, since that triggers an assertion in rustc which
99+ // checks whether the type has escaping regions
100+ if abi != bare_fn_ty. abi ||
101+ sig. variadic != bare_sig. variadic ||
102+ sig. inputs ( ) . len ( ) != bare_sig. inputs ( ) . len ( ) {
94103 return Err ( EvalError :: FunctionPointerTyMismatch ( abi, sig, bare_fn_ty) ) ;
95104 }
96105 self . eval_fn_call ( def_id, substs, bare_fn_ty, destination, args,
@@ -189,15 +198,15 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
189198 use syntax:: abi:: Abi ;
190199 match fn_ty. abi {
191200 Abi :: RustIntrinsic => {
192- let ty = fn_ty. sig . 0 . output ;
201+ let ty = fn_ty. sig . 0 . output ( ) ;
193202 let layout = self . type_layout ( ty) ?;
194203 let ( ret, target) = destination. unwrap ( ) ;
195204 self . call_intrinsic ( def_id, substs, arg_operands, ret, ty, layout, target) ?;
196205 Ok ( ( ) )
197206 }
198207
199208 Abi :: C => {
200- let ty = fn_ty. sig . 0 . output ;
209+ let ty = fn_ty. sig . 0 . output ( ) ;
201210 let ( ret, target) = destination. unwrap ( ) ;
202211 self . call_c_abi ( def_id, arg_operands, ret, ty) ?;
203212 self . goto_block ( target) ;
@@ -320,11 +329,6 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
320329 . collect ( ) ;
321330 let args = args_res?;
322331
323- if link_name. starts_with ( "pthread_" ) {
324- warn ! ( "ignoring C ABI call: {}" , link_name) ;
325- return Ok ( ( ) ) ;
326- }
327-
328332 let usize = self . tcx . types . usize ;
329333
330334 match & link_name[ ..] {
@@ -371,6 +375,37 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
371375 self . write_primval ( dest, PrimVal :: new ( result as u64 ) , dest_ty) ?;
372376 }
373377
378+ "memchr" => {
379+ let ptr = args[ 0 ] . read_ptr ( & self . memory ) ?;
380+ let val = self . value_to_primval ( args[ 1 ] , usize) ?. to_u64 ( ) as u8 ;
381+ let num = self . value_to_primval ( args[ 2 ] , usize) ?. to_u64 ( ) ;
382+ if let Some ( idx) = self . memory . read_bytes ( ptr, num) ?. iter ( ) . position ( |& c| c == val) {
383+ let new_ptr = ptr. offset ( idx as u64 ) ;
384+ self . write_value ( Value :: ByVal ( PrimVal :: from_ptr ( new_ptr) ) , dest, dest_ty) ?;
385+ } else {
386+ self . write_value ( Value :: ByVal ( PrimVal :: new ( 0 ) ) , dest, dest_ty) ?;
387+ }
388+ }
389+
390+ "getenv" => {
391+ {
392+ let name_ptr = args[ 0 ] . read_ptr ( & self . memory ) ?;
393+ let name = self . memory . read_c_str ( name_ptr) ?;
394+ info ! ( "ignored env var request for `{:?}`" , :: std:: str :: from_utf8( name) ) ;
395+ }
396+ self . write_value ( Value :: ByVal ( PrimVal :: new ( 0 ) ) , dest, dest_ty) ?;
397+ }
398+
399+ // unix panic code inside libstd will read the return value of this function
400+ "pthread_rwlock_rdlock" => {
401+ self . write_primval ( dest, PrimVal :: new ( 0 ) , dest_ty) ?;
402+ }
403+
404+ link_name if link_name. starts_with ( "pthread_" ) => {
405+ warn ! ( "ignoring C ABI call: {}" , link_name) ;
406+ return Ok ( ( ) ) ;
407+ } ,
408+
374409 _ => {
375410 return Err ( EvalError :: Unimplemented ( format ! ( "can't call C ABI function: {}" , link_name) ) ) ;
376411 }
@@ -520,7 +555,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
520555 let offset = idx * self . memory . pointer_size ( ) ;
521556 let fn_ptr = self . memory . read_ptr ( vtable. offset ( offset) ) ?;
522557 let ( def_id, substs, _abi, sig) = self . memory . get_fn ( fn_ptr. alloc_id ) ?;
523- * first_ty = sig. inputs [ 0 ] ;
558+ * first_ty = sig. inputs ( ) [ 0 ] ;
524559 Ok ( ( def_id, substs, Vec :: new ( ) ) )
525560 } else {
526561 Err ( EvalError :: VtableForArgumentlessMethod )
@@ -664,7 +699,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
664699 // some values don't need to call a drop impl, so the value is null
665700 if drop_fn != Pointer :: from_int ( 0 ) {
666701 let ( def_id, substs, _abi, sig) = self . memory . get_fn ( drop_fn. alloc_id ) ?;
667- let real_ty = sig. inputs [ 0 ] ;
702+ let real_ty = sig. inputs ( ) [ 0 ] ;
668703 self . drop ( Lvalue :: from_ptr ( ptr) , real_ty, drop) ?;
669704 drop. push ( ( def_id, Value :: ByVal ( PrimVal :: from_ptr ( ptr) ) , substs) ) ;
670705 } else {
0 commit comments