@@ -394,17 +394,32 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
394394 )
395395 }
396396
397+ /// Get last error variable as a place, lazily allocating thread-local storage for it if
398+ /// necessary.
399+ fn last_error_place ( & mut self ) -> InterpResult < ' tcx , MPlaceTy < ' tcx , Tag > > {
400+ let this = self . eval_context_mut ( ) ;
401+ if let Some ( errno_place) = this. active_thread_ref ( ) . last_error {
402+ Ok ( errno_place)
403+ } else {
404+ let errno_layout = this. machine . layouts . u32 ;
405+ let errno_place = this. allocate ( errno_layout, MiriMemoryKind :: Machine . into ( ) ) ;
406+ this. write_scalar ( Scalar :: from_u32 ( 0 ) , errno_place. into ( ) ) ?;
407+ this. active_thread_mut ( ) . last_error = Some ( errno_place) ;
408+ Ok ( errno_place)
409+ }
410+ }
411+
397412 /// Sets the last error variable.
398413 fn set_last_error ( & mut self , scalar : Scalar < Tag > ) -> InterpResult < ' tcx > {
399414 let this = self . eval_context_mut ( ) ;
400- let errno_place = this. machine . last_error . unwrap ( ) ;
415+ let errno_place = this. last_error_place ( ) ? ;
401416 this. write_scalar ( scalar, errno_place. into ( ) )
402417 }
403418
404419 /// Gets the last error variable.
405- fn get_last_error ( & self ) -> InterpResult < ' tcx , Scalar < Tag > > {
406- let this = self . eval_context_ref ( ) ;
407- let errno_place = this. machine . last_error . unwrap ( ) ;
420+ fn get_last_error ( & mut self ) -> InterpResult < ' tcx , Scalar < Tag > > {
421+ let this = self . eval_context_mut ( ) ;
422+ let errno_place = this. last_error_place ( ) ? ;
408423 this. read_scalar ( errno_place. into ( ) ) ?. check_init ( )
409424 }
410425
0 commit comments