@@ -306,11 +306,24 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
306
306
///
307
307
/// Most of the time you should use `check_mplace_access`, but when you just have a pointer,
308
308
/// this method is still appropriate.
309
+ #[ inline( always) ]
309
310
pub fn check_ptr_access (
310
311
& self ,
311
312
sptr : Scalar < M :: PointerTag > ,
312
313
size : Size ,
313
314
align : Align ,
315
+ ) -> InterpResult < ' tcx , Option < Pointer < M :: PointerTag > > > {
316
+ let align = if M :: CHECK_ALIGN { Some ( align) } else { None } ;
317
+ self . check_ptr_access_align ( sptr, size, align)
318
+ }
319
+
320
+ /// Like `check_ptr_access`, but *definitely* checks alignment when `align`
321
+ /// is `Some` (overriding `M::CHECK_ALIGN`).
322
+ pub ( super ) fn check_ptr_access_align (
323
+ & self ,
324
+ sptr : Scalar < M :: PointerTag > ,
325
+ size : Size ,
326
+ align : Option < Align > ,
314
327
) -> InterpResult < ' tcx , Option < Pointer < M :: PointerTag > > > {
315
328
fn check_offset_align ( offset : u64 , align : Align ) -> InterpResult < ' static > {
316
329
if offset % align. bytes ( ) == 0 {
@@ -338,11 +351,14 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
338
351
Ok ( bits) => {
339
352
let bits = bits as u64 ; // it's ptr-sized
340
353
assert ! ( size. bytes( ) == 0 ) ;
341
- // Must be non-NULL and aligned .
354
+ // Must be non-NULL.
342
355
if bits == 0 {
343
356
throw_unsup ! ( InvalidNullPointerUsage )
344
357
}
345
- check_offset_align ( bits, align) ?;
358
+ // Must be aligned.
359
+ if let Some ( align) = align {
360
+ check_offset_align ( bits, align) ?;
361
+ }
346
362
None
347
363
}
348
364
Err ( ptr) => {
@@ -355,18 +371,20 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
355
371
end_ptr. check_in_alloc ( allocation_size, CheckInAllocMsg :: MemoryAccessTest ) ?;
356
372
// Test align. Check this last; if both bounds and alignment are violated
357
373
// we want the error to be about the bounds.
358
- if alloc_align. bytes ( ) < align. bytes ( ) {
359
- // The allocation itself is not aligned enough.
360
- // FIXME: Alignment check is too strict, depending on the base address that
361
- // got picked we might be aligned even if this check fails.
362
- // We instead have to fall back to converting to an integer and checking
363
- // the "real" alignment.
364
- throw_unsup ! ( AlignmentCheckFailed {
365
- has: alloc_align,
366
- required: align,
367
- } )
374
+ if let Some ( align) = align {
375
+ if alloc_align. bytes ( ) < align. bytes ( ) {
376
+ // The allocation itself is not aligned enough.
377
+ // FIXME: Alignment check is too strict, depending on the base address that
378
+ // got picked we might be aligned even if this check fails.
379
+ // We instead have to fall back to converting to an integer and checking
380
+ // the "real" alignment.
381
+ throw_unsup ! ( AlignmentCheckFailed {
382
+ has: alloc_align,
383
+ required: align,
384
+ } ) ;
385
+ }
386
+ check_offset_align ( ptr. offset . bytes ( ) , align) ?;
368
387
}
369
- check_offset_align ( ptr. offset . bytes ( ) , align) ?;
370
388
371
389
// We can still be zero-sized in this branch, in which case we have to
372
390
// return `None`.
0 commit comments