@@ -286,19 +286,16 @@ fn condattr_get_clock_id<'tcx>(
286
286
. to_i32 ( )
287
287
}
288
288
289
- fn translate_clock_id < ' tcx > (
290
- ecx : & MiriInterpCx < ' tcx > ,
291
- raw_id : i32 ,
292
- ) -> InterpResult < ' tcx , ClockType > {
289
+ fn translate_clock_id < ' tcx > ( ecx : & MiriInterpCx < ' tcx > , raw_id : i32 ) -> InterpResult < ' tcx , ClockId > {
293
290
// To ensure compatibility with PTHREAD_COND_INITIALIZER on all platforms,
294
291
// we can't just compare with CLOCK_REALTIME: on Solarish, PTHREAD_COND_INITIALIZER
295
292
// makes the clock 0 but CLOCK_REALTIME is 3.
296
293
Ok ( if raw_id == ecx. eval_libc_i32 ( "CLOCK_REALTIME" ) || raw_id == 0 {
297
- ClockType :: Realtime
294
+ ClockId :: Realtime
298
295
} else if raw_id == ecx. eval_libc_i32 ( "CLOCK_MONOTONIC" ) {
299
- ClockType :: Monotonic
296
+ ClockId :: Monotonic
300
297
} else {
301
- throw_unsup_format ! ( "unsupported type of clock id: {raw_id}" ) ;
298
+ throw_unsup_format ! ( "unsupported clock id: {raw_id}" ) ;
302
299
} )
303
300
}
304
301
@@ -363,7 +360,7 @@ fn cond_clock_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> u64 {
363
360
let id = ecx. read_scalar ( & id_field) . unwrap ( ) . to_i32 ( ) . unwrap ( ) ;
364
361
let id = translate_clock_id ( ecx, id) . expect ( "static initializer should be valid" ) ;
365
362
assert ! (
366
- matches!( id, ClockType :: Realtime ) ,
363
+ matches!( id, ClockId :: Realtime ) ,
367
364
"PTHREAD_COND_INITIALIZER is incompatible with our pthread_cond layout: clock is not CLOCK_REALTIME"
368
365
) ;
369
366
}
@@ -372,7 +369,7 @@ fn cond_clock_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> u64 {
372
369
}
373
370
374
371
#[ derive( Debug , Clone , Copy ) ]
375
- enum ClockType {
372
+ enum ClockId {
376
373
Realtime ,
377
374
Monotonic ,
378
375
}
@@ -383,8 +380,8 @@ struct AdditionalCondData {
383
380
/// The address of the cond.
384
381
address : u64 ,
385
382
386
- /// The clock type of the cond.
387
- clock_type : ClockType ,
383
+ /// The clock id of the cond.
384
+ clock_id : ClockId ,
388
385
}
389
386
390
387
fn cond_get_id < ' tcx > (
@@ -399,8 +396,8 @@ fn cond_get_id<'tcx>(
399
396
} else {
400
397
cond_get_clock_id ( ecx, cond_ptr) ?
401
398
} ;
402
- let clock_type = translate_clock_id ( ecx, raw_id) ?;
403
- Ok ( Some ( Box :: new ( AdditionalCondData { address, clock_type } ) ) )
399
+ let clock_id = translate_clock_id ( ecx, raw_id) ?;
400
+ Ok ( Some ( Box :: new ( AdditionalCondData { address, clock_id } ) ) )
404
401
} ) ?;
405
402
406
403
// Check that the mutex has not been moved since last use.
@@ -835,14 +832,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
835
832
} else {
836
833
condattr_get_clock_id ( this, attr_op) ?
837
834
} ;
838
- let clock_type = translate_clock_id ( this, clock_id) ?;
835
+ let clock_id = translate_clock_id ( this, clock_id) ?;
839
836
840
837
let cond = this. deref_pointer ( cond_op) ?;
841
838
let address = cond. ptr ( ) . addr ( ) . bytes ( ) ;
842
839
this. condvar_create (
843
840
& cond,
844
841
cond_id_offset ( this) ?,
845
- Some ( Box :: new ( AdditionalCondData { address, clock_type } ) ) ,
842
+ Some ( Box :: new ( AdditionalCondData { address, clock_id } ) ) ,
846
843
) ?;
847
844
848
845
Ok ( ( ) )
@@ -898,10 +895,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
898
895
let mutex_id = mutex_get_id ( this, mutex_op) ?;
899
896
900
897
// Extract the timeout.
901
- let clock_type = this
898
+ let clock_id = this
902
899
. condvar_get_data :: < AdditionalCondData > ( id)
903
900
. expect ( "additional data should always be present for pthreads" )
904
- . clock_type ;
901
+ . clock_id ;
905
902
let duration = match this
906
903
. read_timespec ( & this. deref_pointer_as ( abstime_op, this. libc_ty_layout ( "timespec" ) ) ?) ?
907
904
{
@@ -912,13 +909,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
912
909
return Ok ( ( ) ) ;
913
910
}
914
911
} ;
915
- let timeout_clock = if matches ! ( clock_type, ClockType :: Realtime ) {
916
- this. check_no_isolation ( "`pthread_cond_timedwait` with `CLOCK_REALTIME`" ) ?;
917
- TimeoutClock :: RealTime
918
- } else if let ClockType :: Monotonic = clock_type {
919
- TimeoutClock :: Monotonic
920
- } else {
921
- throw_unsup_format ! ( "unsupported clock id: {clock_type:?}" ) ;
912
+ let timeout_clock = match clock_id {
913
+ ClockId :: Realtime => {
914
+ this. check_no_isolation ( "`pthread_cond_timedwait` with `CLOCK_REALTIME`" ) ?;
915
+ TimeoutClock :: RealTime
916
+ }
917
+ ClockId :: Monotonic => TimeoutClock :: Monotonic ,
922
918
} ;
923
919
924
920
this. condvar_wait (
@@ -934,16 +930,16 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
934
930
}
935
931
936
932
fn pthread_cond_destroy ( & mut self , cond_op : & OpTy < ' tcx > ) -> InterpResult < ' tcx , ( ) > {
933
+ //NOTE: Destroying an uninit pthread_cond is UB. Make sure it's not uninit,
934
+ // by accessing at least once all of its fields that we use.
935
+
937
936
let this = self . eval_context_mut ( ) ;
938
937
939
938
let id = cond_get_id ( this, cond_op) ?;
940
939
if this. condvar_is_awaited ( id) {
941
940
throw_ub_format ! ( "destroying an awaited conditional variable" ) ;
942
941
}
943
942
944
- // Destroying an uninit pthread_cond is UB, so check to make sure it's not uninit.
945
- cond_get_id ( this, cond_op) ?;
946
-
947
943
// This might lead to false positives, see comment in pthread_mutexattr_destroy
948
944
this. write_uninit ( & this. deref_pointer_as ( cond_op, this. libc_ty_layout ( "pthread_cond_t" ) ) ?) ?;
949
945
// FIXME: delete interpreter state associated with this condvar.
0 commit comments