@@ -168,11 +168,29 @@ impl fmt::Display for MiriMemoryKind {
168168/// Pointer provenance.
169169#[ derive( Clone , Copy ) ]
170170pub enum Provenance {
171+ /// For pointers with concrete provenance. we exactly know which allocation they are attached to
172+ /// and what their borrow tag is.
171173 Concrete {
172174 alloc_id : AllocId ,
173175 /// Borrow Tracker tag.
174176 tag : BorTag ,
175177 } ,
178+ /// Pointers with wildcard provenance are created on int-to-ptr casts. According to the
179+ /// specification, we should at that point angelically "guess" a provenance that will make all
180+ /// future uses of this pointer work, if at all possible. Of course such a semantics cannot be
181+ /// actually implemented in Miri. So instead, we approximate this, erroring on the side of
182+ /// accepting too much code rather than rejecting correct code: a pointer with wildcard
183+ /// provenance "acts like" any previously exposed pointer. Each time it is used, we check
184+ /// whether *some* exposed pointer could have done what we want to do, and if the answer is yes
185+ /// then we allow the access. This allows too much code in two ways:
186+ /// - The same wildcard pointer can "take the role" of multiple different exposed pointers on
187+ /// subsequenct memory accesses.
188+ /// - In the aliasing model, we don't just have to know the borrow tag of the pointer used for
189+ /// the access, we also have to update the aliasing state -- and that update can be very
190+ /// different depending on which borrow tag we pick! Stacked Borrows has support for this by
191+ /// switching to a stack that is only approximately known, i.e. we overapproximate the effect
192+ /// of using *any* exposed pointer for this access, and only keep information about the borrow
193+ /// stack that would be true with all possible choices.
176194 Wildcard ,
177195}
178196
@@ -1122,19 +1140,16 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
11221140 _ => { }
11231141 }
11241142 }
1125- let absolute_addr = intptrcast:: GlobalStateInner :: rel_ptr_to_addr ( ecx, ptr) ?;
11261143 let tag = if let Some ( borrow_tracker) = & ecx. machine . borrow_tracker {
11271144 borrow_tracker. borrow_mut ( ) . base_ptr_tag ( ptr. provenance , & ecx. machine )
11281145 } else {
11291146 // Value does not matter, SB is disabled
11301147 BorTag :: default ( )
11311148 } ;
1132- Ok ( Pointer :: new (
1133- Provenance :: Concrete { alloc_id : ptr. provenance , tag } ,
1134- Size :: from_bytes ( absolute_addr) ,
1135- ) )
1149+ intptrcast:: GlobalStateInner :: ptr_from_rel_ptr ( ecx, ptr, tag)
11361150 }
11371151
1152+ /// Called on `usize as ptr` casts.
11381153 #[ inline( always) ]
11391154 fn ptr_from_addr_cast (
11401155 ecx : & MiriInterpCx < ' mir , ' tcx > ,
@@ -1143,6 +1158,9 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
11431158 intptrcast:: GlobalStateInner :: ptr_from_addr_cast ( ecx, addr)
11441159 }
11451160
1161+ /// Called on `ptr as usize` casts.
1162+ /// (Actually computing the resulting `usize` doesn't need machine help,
1163+ /// that's just `Scalar::try_to_int`.)
11461164 fn expose_ptr (
11471165 ecx : & mut InterpCx < ' mir , ' tcx , Self > ,
11481166 ptr : Pointer < Self :: Provenance > ,
@@ -1160,11 +1178,17 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
11601178
11611179 /// Convert a pointer with provenance into an allocation-offset pair,
11621180 /// or a `None` with an absolute address if that conversion is not possible.
1181+ ///
1182+ /// This is called when a pointer is about to be used for memory access,
1183+ /// an in-bounds check, or anything else that requires knowing which allocation it points to.
1184+ /// The resulting `AllocId` will just be used for that one step and the forgotten again
1185+ /// (i.e., we'll never turn the data returned here back into a `Pointer` that might be
1186+ /// stored in machine state).
11631187 fn ptr_get_alloc (
11641188 ecx : & MiriInterpCx < ' mir , ' tcx > ,
11651189 ptr : Pointer < Self :: Provenance > ,
11661190 ) -> Option < ( AllocId , Size , Self :: ProvenanceExtra ) > {
1167- let rel = intptrcast:: GlobalStateInner :: abs_ptr_to_rel ( ecx, ptr) ;
1191+ let rel = intptrcast:: GlobalStateInner :: ptr_get_alloc ( ecx, ptr) ;
11681192
11691193 rel. map ( |( alloc_id, size) | {
11701194 let tag = match ptr. provenance {
0 commit comments