@@ -5,16 +5,18 @@ use rustc_abi::Size;
5
5
use rustc_const_eval:: interpret:: { InterpResult , interp_ok} ;
6
6
use rustc_data_structures:: fx:: FxHashSet ;
7
7
use rustc_middle:: mir;
8
+ use rustc_middle:: mir:: interpret;
8
9
use rustc_middle:: ty:: ScalarInt ;
9
10
use rustc_span:: Span ;
10
11
use tracing:: debug;
11
12
12
13
use super :: GenmcScalar ;
13
- use crate :: diagnostics:: EvalContextExt ;
14
+ use crate :: alloc_addresses:: EvalContextExt as _;
15
+ use crate :: diagnostics:: EvalContextExt as _;
14
16
use crate :: intrinsics:: AtomicRmwOp ;
15
17
use crate :: {
16
- AtomicFenceOrd , AtomicReadOrd , AtomicRwOrd , AtomicWriteOrd , InterpCx , MiriInterpCx ,
17
- MiriMachine , NonHaltingDiagnostic , Scalar , throw_unsup_format,
18
+ AtomicFenceOrd , AtomicReadOrd , AtomicRwOrd , AtomicWriteOrd , BorTag , GenmcCtx , InterpCx ,
19
+ MiriInterpCx , MiriMachine , NonHaltingDiagnostic , Scalar , machine , throw_unsup_format,
18
20
} ;
19
21
20
22
/// Maximum size memory access in bytes that GenMC supports.
@@ -80,19 +82,30 @@ pub fn split_access(address: Size, size: Size) -> impl Iterator<Item = (u64, u64
80
82
/// We cannot use the `AllocId` instead of the base address, since Miri has no control over the `AllocId`, and it may change across executions.
81
83
/// Pointers with `Wildcard` provenance are not supported.
82
84
pub fn scalar_to_genmc_scalar < ' tcx > (
83
- _ecx : & MiriInterpCx < ' tcx > ,
85
+ ecx : & MiriInterpCx < ' tcx > ,
86
+ genmc_ctx : & GenmcCtx ,
84
87
scalar : Scalar ,
85
88
) -> InterpResult < ' tcx , GenmcScalar > {
86
89
interp_ok ( match scalar {
87
90
rustc_const_eval:: interpret:: Scalar :: Int ( scalar_int) => {
88
91
// FIXME(genmc): Add u128 support once GenMC supports it.
89
92
let value: u64 = scalar_int. to_uint ( scalar_int. size ( ) ) . try_into ( ) . unwrap ( ) ;
90
- GenmcScalar { value, is_init : true }
93
+ GenmcScalar { value, extra : 0 , is_init : true }
94
+ }
95
+ rustc_const_eval:: interpret:: Scalar :: Ptr ( pointer, size) => {
96
+ // FIXME(genmc,borrow tracking): Borrow tracking information is lost.
97
+ let addr = crate :: Pointer :: from ( pointer) . addr ( ) ;
98
+ if let crate :: Provenance :: Wildcard = pointer. provenance {
99
+ throw_unsup_format ! ( "Pointers with wildcard provenance not allowed in GenMC mode" ) ;
100
+ }
101
+ let ( alloc_id, _size, _prov_extra) =
102
+ rustc_const_eval:: interpret:: Machine :: ptr_get_alloc ( ecx, pointer, size. into ( ) )
103
+ . unwrap ( ) ;
104
+ let base_addr = ecx. addr_from_alloc_id ( alloc_id, None ) ?;
105
+ // Add the base_addr alloc_id pair to the map.
106
+ genmc_ctx. exec_state . genmc_shared_allocs_map . borrow_mut ( ) . insert ( base_addr, alloc_id) ;
107
+ GenmcScalar { value : addr. bytes ( ) , extra : base_addr, is_init : true }
91
108
}
92
- rustc_const_eval:: interpret:: Scalar :: Ptr ( _pointer, _size) =>
93
- throw_unsup_format ! (
94
- "FIXME(genmc): Implement sending pointers (with provenance) to GenMC."
95
- ) ,
96
109
} )
97
110
}
98
111
@@ -101,16 +114,25 @@ pub fn scalar_to_genmc_scalar<'tcx>(
101
114
/// Convert a `GenmcScalar` back into a Miri `Scalar`.
102
115
/// For pointers, attempt to convert the stored base address of their allocation back into an `AllocId`.
103
116
pub fn genmc_scalar_to_scalar < ' tcx > (
104
- _ecx : & MiriInterpCx < ' tcx > ,
117
+ ecx : & MiriInterpCx < ' tcx > ,
118
+ genmc_ctx : & GenmcCtx ,
105
119
scalar : GenmcScalar ,
106
120
size : Size ,
107
121
) -> InterpResult < ' tcx , Scalar > {
108
- // FIXME(genmc): Add GenmcScalar to Miri Pointer conversion.
109
-
110
- // NOTE: GenMC always returns 64 bit values, and the upper bits are not yet truncated.
111
- // FIXME(genmc): GenMC should be doing the truncation, not Miri.
112
- let ( value_scalar_int, _got_truncated) = ScalarInt :: truncate_from_uint ( scalar. value , size) ;
113
- interp_ok ( Scalar :: Int ( value_scalar_int) )
122
+ // If `extra` is zero, we have a regular integer.
123
+ if scalar. extra == 0 {
124
+ // NOTE: GenMC always returns 64 bit values, and the upper bits are not yet truncated.
125
+ // FIXME(genmc): GenMC should be doing the truncation, not Miri.
126
+ let ( value_scalar_int, _got_truncated) = ScalarInt :: truncate_from_uint ( scalar. value , size) ;
127
+ return interp_ok ( Scalar :: from ( value_scalar_int) ) ;
128
+ }
129
+ // `extra` is non-zero, we have a pointer.
130
+ // When we get a pointer from GenMC, then we must have sent it to GenMC before in the same execution (since the reads-from relation is always respected).
131
+ let alloc_id = genmc_ctx. exec_state . genmc_shared_allocs_map . borrow ( ) [ & scalar. extra ] ;
132
+ // FIXME(genmc,borrow tracking): Borrow tracking not yet supported.
133
+ let provenance = machine:: Provenance :: Concrete { alloc_id, tag : BorTag :: default ( ) } ;
134
+ let ptr = interpret:: Pointer :: new ( provenance, Size :: from_bytes ( scalar. value ) ) ;
135
+ interp_ok ( Scalar :: from_pointer ( ptr, & ecx. tcx ) )
114
136
}
115
137
116
138
impl AtomicReadOrd {
0 commit comments