@@ -7,7 +7,7 @@ use super::{
7
7
8
8
use crate :: ty:: layout:: { Size , Align } ;
9
9
use syntax:: ast:: Mutability ;
10
- use std:: iter;
10
+ use std:: { iter, fmt :: { self , Display } } ;
11
11
use crate :: mir;
12
12
use std:: ops:: { Deref , DerefMut } ;
13
13
use rustc_data_structures:: sorted_map:: SortedMap ;
@@ -22,6 +22,28 @@ pub enum InboundsCheck {
22
22
MaybeDead ,
23
23
}
24
24
25
+ /// Used by `check_in_alloc` to indicate context of check
26
+ #[ derive( Debug , Copy , Clone , RustcEncodable , RustcDecodable , HashStable ) ]
27
+ pub enum CheckInAllocMsg {
28
+ MemoryAccessTest ,
29
+ NullPointerTest ,
30
+ PointerArithmeticTest ,
31
+ InboundsTest ,
32
+ }
33
+
34
+ impl Display for CheckInAllocMsg {
35
+ /// When this is printed as an error the context looks like this
36
+ /// "{test name} failed: pointer must be in-bounds at offset..."
37
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
38
+ write ! ( f, "{}" , match * self {
39
+ CheckInAllocMsg :: MemoryAccessTest => "Memory access" ,
40
+ CheckInAllocMsg :: NullPointerTest => "Null pointer test" ,
41
+ CheckInAllocMsg :: PointerArithmeticTest => "Pointer arithmetic" ,
42
+ CheckInAllocMsg :: InboundsTest => "Inbounds test" ,
43
+ } )
44
+ }
45
+ }
46
+
25
47
#[ derive( Clone , Debug , Eq , PartialEq , PartialOrd , Ord , Hash , RustcEncodable , RustcDecodable ) ]
26
48
pub struct Allocation < Tag =( ) , Extra =( ) > {
27
49
/// The actual bytes of the allocation.
@@ -131,9 +153,10 @@ impl<'tcx, Tag, Extra> Allocation<Tag, Extra> {
131
153
fn check_bounds_ptr (
132
154
& self ,
133
155
ptr : Pointer < Tag > ,
156
+ msg : CheckInAllocMsg ,
134
157
) -> EvalResult < ' tcx > {
135
158
let allocation_size = self . bytes . len ( ) as u64 ;
136
- ptr. check_in_alloc ( Size :: from_bytes ( allocation_size) , InboundsCheck :: Live )
159
+ ptr. check_in_alloc ( Size :: from_bytes ( allocation_size) , msg )
137
160
}
138
161
139
162
/// Checks if the memory range beginning at `ptr` and of size `Size` is "in-bounds".
@@ -143,9 +166,10 @@ impl<'tcx, Tag, Extra> Allocation<Tag, Extra> {
143
166
cx : & impl HasDataLayout ,
144
167
ptr : Pointer < Tag > ,
145
168
size : Size ,
169
+ msg : CheckInAllocMsg ,
146
170
) -> EvalResult < ' tcx > {
147
171
// if ptr.offset is in bounds, then so is ptr (because offset checks for overflow)
148
- self . check_bounds_ptr ( ptr. offset ( size, cx) ?)
172
+ self . check_bounds_ptr ( ptr. offset ( size, cx) ?, msg )
149
173
}
150
174
}
151
175
@@ -164,9 +188,10 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
164
188
ptr : Pointer < Tag > ,
165
189
size : Size ,
166
190
check_defined_and_ptr : bool ,
191
+ msg : CheckInAllocMsg ,
167
192
) -> EvalResult < ' tcx , & [ u8 ] >
168
193
{
169
- self . check_bounds ( cx, ptr, size) ?;
194
+ self . check_bounds ( cx, ptr, size, msg ) ?;
170
195
171
196
if check_defined_and_ptr {
172
197
self . check_defined ( ptr, size) ?;
@@ -192,7 +217,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
192
217
size : Size ,
193
218
) -> EvalResult < ' tcx , & [ u8 ] >
194
219
{
195
- self . get_bytes_internal ( cx, ptr, size, true )
220
+ self . get_bytes_internal ( cx, ptr, size, true , CheckInAllocMsg :: MemoryAccessTest )
196
221
}
197
222
198
223
/// It is the caller's responsibility to handle undefined and pointer bytes.
@@ -205,7 +230,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
205
230
size : Size ,
206
231
) -> EvalResult < ' tcx , & [ u8 ] >
207
232
{
208
- self . get_bytes_internal ( cx, ptr, size, false )
233
+ self . get_bytes_internal ( cx, ptr, size, false , CheckInAllocMsg :: MemoryAccessTest )
209
234
}
210
235
211
236
/// Just calling this already marks everything as defined and removes relocations,
@@ -218,7 +243,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
218
243
) -> EvalResult < ' tcx , & mut [ u8 ] >
219
244
{
220
245
assert_ne ! ( size. bytes( ) , 0 , "0-sized accesses should never even get a `Pointer`" ) ;
221
- self . check_bounds ( cx, ptr, size) ?;
246
+ self . check_bounds ( cx, ptr, size, CheckInAllocMsg :: MemoryAccessTest ) ?;
222
247
223
248
self . mark_definedness ( ptr, size, true ) ?;
224
249
self . clear_relocations ( cx, ptr, size) ?;
0 commit comments