@@ -7,7 +7,7 @@ use super::{
77
88use crate :: ty:: layout:: { Size , Align } ;
99use syntax:: ast:: Mutability ;
10- use std:: iter;
10+ use std:: { iter, fmt :: { self , Display } } ;
1111use crate :: mir;
1212use std:: ops:: { Deref , DerefMut } ;
1313use rustc_data_structures:: sorted_map:: SortedMap ;
@@ -22,6 +22,44 @@ pub enum InboundsCheck {
2222 MaybeDead ,
2323}
2424
25+ /// Used by `check_in_alloc` to indicate whether the pointer needs to be just inbounds
26+ /// or also inbounds of a *live* allocation.
27+ #[ derive( Debug , Copy , Clone , RustcEncodable , RustcDecodable , HashStable ) ]
28+ pub enum CheckInAllocMsg {
29+ ReadCStr ,
30+ CheckBytes ,
31+ WriteBytes ,
32+ WriteRepeat ,
33+ ReadScalar ,
34+ WriteScalar ,
35+ SlicePatCoveredByConst ,
36+ ReadDiscriminant ,
37+ CheckAlign ,
38+ ReadBytes ,
39+ CopyRepeatedly ,
40+ CheckBounds ,
41+ }
42+
43+ impl Display for CheckInAllocMsg {
44+
45+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
46+ write ! ( f, "{}" , match * self {
47+ CheckInAllocMsg :: ReadCStr => "read C str" ,
48+ CheckInAllocMsg :: CheckBytes => "check bytes" ,
49+ CheckInAllocMsg :: WriteBytes => "write bytes" ,
50+ CheckInAllocMsg :: WriteRepeat => "write repeat" ,
51+ CheckInAllocMsg :: ReadScalar => "read scalar" ,
52+ CheckInAllocMsg :: WriteScalar => "write scalar" ,
53+ CheckInAllocMsg :: SlicePatCoveredByConst => "slice pat covered by const" ,
54+ CheckInAllocMsg :: ReadDiscriminant => "read discriminant" ,
55+ CheckInAllocMsg :: CheckAlign => "check align" ,
56+ CheckInAllocMsg :: ReadBytes => "read bytes" ,
57+ CheckInAllocMsg :: CopyRepeatedly => "copy repeatedly" ,
58+ CheckInAllocMsg :: CheckBounds => "check bounds" ,
59+ } )
60+ }
61+ }
62+
2563#[ derive( Clone , Debug , Eq , PartialEq , PartialOrd , Ord , Hash , RustcEncodable , RustcDecodable ) ]
2664pub struct Allocation < Tag =( ) , Extra =( ) > {
2765 /// The actual bytes of the allocation.
@@ -140,9 +178,10 @@ impl<'tcx, Tag, Extra> Allocation<Tag, Extra> {
140178 fn check_bounds_ptr (
141179 & self ,
142180 ptr : Pointer < Tag > ,
181+ msg : CheckInAllocMsg ,
143182 ) -> EvalResult < ' tcx > {
144183 let allocation_size = self . bytes . len ( ) as u64 ;
145- ptr. check_in_alloc ( Size :: from_bytes ( allocation_size) , InboundsCheck :: Live )
184+ ptr. check_in_alloc ( Size :: from_bytes ( allocation_size) , msg )
146185 }
147186
148187 /// Checks if the memory range beginning at `ptr` and of size `Size` is "in-bounds".
@@ -152,9 +191,10 @@ impl<'tcx, Tag, Extra> Allocation<Tag, Extra> {
152191 cx : & impl HasDataLayout ,
153192 ptr : Pointer < Tag > ,
154193 size : Size ,
194+ msg : CheckInAllocMsg ,
155195 ) -> EvalResult < ' tcx > {
156196 // if ptr.offset is in bounds, then so is ptr (because offset checks for overflow)
157- self . check_bounds_ptr ( ptr. offset ( size, cx) ?)
197+ self . check_bounds_ptr ( ptr. offset ( size, cx) ?, msg )
158198 }
159199}
160200
@@ -173,11 +213,12 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
173213 ptr : Pointer < Tag > ,
174214 size : Size ,
175215 check_defined_and_ptr : bool ,
216+ msg : CheckInAllocMsg ,
176217 ) -> EvalResult < ' tcx , & [ u8 ] >
177218 // FIXME: Working around https://github.com/rust-lang/rust/issues/56209
178219 where Extra : AllocationExtra < Tag , MemoryExtra >
179220 {
180- self . check_bounds ( cx, ptr, size) ?;
221+ self . check_bounds ( cx, ptr, size, msg ) ?;
181222
182223 if check_defined_and_ptr {
183224 self . check_defined ( ptr, size) ?;
@@ -201,11 +242,12 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
201242 cx : & impl HasDataLayout ,
202243 ptr : Pointer < Tag > ,
203244 size : Size ,
245+ msg : CheckInAllocMsg ,
204246 ) -> EvalResult < ' tcx , & [ u8 ] >
205247 // FIXME: Working around https://github.com/rust-lang/rust/issues/56209
206248 where Extra : AllocationExtra < Tag , MemoryExtra >
207249 {
208- self . get_bytes_internal ( cx, ptr, size, true )
250+ self . get_bytes_internal ( cx, ptr, size, true , msg )
209251 }
210252
211253 /// It is the caller's responsibility to handle undefined and pointer bytes.
@@ -216,11 +258,12 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
216258 cx : & impl HasDataLayout ,
217259 ptr : Pointer < Tag > ,
218260 size : Size ,
261+ msg : CheckInAllocMsg ,
219262 ) -> EvalResult < ' tcx , & [ u8 ] >
220263 // FIXME: Working around https://github.com/rust-lang/rust/issues/56209
221264 where Extra : AllocationExtra < Tag , MemoryExtra >
222265 {
223- self . get_bytes_internal ( cx, ptr, size, false )
266+ self . get_bytes_internal ( cx, ptr, size, false , msg )
224267 }
225268
226269 /// Just calling this already marks everything as defined and removes relocations,
@@ -230,12 +273,13 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
230273 cx : & impl HasDataLayout ,
231274 ptr : Pointer < Tag > ,
232275 size : Size ,
276+ msg : CheckInAllocMsg ,
233277 ) -> EvalResult < ' tcx , & mut [ u8 ] >
234278 // FIXME: Working around https://github.com/rust-lang/rust/issues/56209
235279 where Extra : AllocationExtra < Tag , MemoryExtra >
236280 {
237281 assert_ne ! ( size. bytes( ) , 0 , "0-sized accesses should never even get a `Pointer`" ) ;
238- self . check_bounds ( cx, ptr, size) ?;
282+ self . check_bounds ( cx, ptr, size, msg ) ?;
239283
240284 self . mark_definedness ( ptr, size, true ) ?;
241285 self . clear_relocations ( cx, ptr, size) ?;
@@ -269,7 +313,7 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
269313 // Go through `get_bytes` for checks and AllocationExtra hooks.
270314 // We read the null, so we include it in the request, but we want it removed
271315 // from the result!
272- Ok ( & self . get_bytes ( cx, ptr, size_with_null) ?[ ..size] )
316+ Ok ( & self . get_bytes ( cx, ptr, size_with_null, CheckInAllocMsg :: ReadCStr ) ?[ ..size] )
273317 }
274318 None => err ! ( UnterminatedCString ( ptr. erase_tag( ) ) ) ,
275319 }
@@ -289,7 +333,7 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
289333 where Extra : AllocationExtra < Tag , MemoryExtra >
290334 {
291335 // Check bounds and relocations on the edges
292- self . get_bytes_with_undef_and_ptr ( cx, ptr, size) ?;
336+ self . get_bytes_with_undef_and_ptr ( cx, ptr, size, CheckInAllocMsg :: CheckBytes ) ?;
293337 // Check undef and ptr
294338 if !allow_ptr_and_undef {
295339 self . check_defined ( ptr, size) ?;
@@ -310,7 +354,7 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
310354 // FIXME: Working around https://github.com/rust-lang/rust/issues/56209
311355 where Extra : AllocationExtra < Tag , MemoryExtra >
312356 {
313- let bytes = self . get_bytes_mut ( cx, ptr, Size :: from_bytes ( src. len ( ) as u64 ) ) ?;
357+ let bytes = self . get_bytes_mut ( cx, ptr, Size :: from_bytes ( src. len ( ) as u64 ) , CheckInAllocMsg :: WriteBytes ) ?;
314358 bytes. clone_from_slice ( src) ;
315359 Ok ( ( ) )
316360 }
@@ -326,7 +370,7 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
326370 // FIXME: Working around https://github.com/rust-lang/rust/issues/56209
327371 where Extra : AllocationExtra < Tag , MemoryExtra >
328372 {
329- let bytes = self . get_bytes_mut ( cx, ptr, count) ?;
373+ let bytes = self . get_bytes_mut ( cx, ptr, count, CheckInAllocMsg :: WriteRepeat ) ?;
330374 for b in bytes {
331375 * b = val;
332376 }
@@ -351,7 +395,7 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
351395 where Extra : AllocationExtra < Tag , MemoryExtra >
352396 {
353397 // get_bytes_unchecked tests relocation edges
354- let bytes = self . get_bytes_with_undef_and_ptr ( cx, ptr, size) ?;
398+ let bytes = self . get_bytes_with_undef_and_ptr ( cx, ptr, size, CheckInAllocMsg :: ReadScalar ) ?;
355399 // Undef check happens *after* we established that the alignment is correct.
356400 // We must not return Ok() for unaligned pointers!
357401 if self . check_defined ( ptr, size) . is_err ( ) {
@@ -428,7 +472,7 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
428472 } ;
429473
430474 let endian = cx. data_layout ( ) . endian ;
431- let dst = self . get_bytes_mut ( cx, ptr, type_size) ?;
475+ let dst = self . get_bytes_mut ( cx, ptr, type_size, CheckInAllocMsg :: WriteScalar ) ?;
432476 write_target_uint ( endian, dst, bytes) . unwrap ( ) ;
433477
434478 // See if we have to also write a relocation
0 commit comments