Skip to content

Commit 326f631

Browse files
author
Lukas Markeffsky
committed
add coretests for const align_offset
1 parent 651ee57 commit 326f631

File tree

2 files changed

+162
-0
lines changed

2 files changed

+162
-0
lines changed

library/core/tests/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#![feature(array_windows)]
55
#![feature(bigint_helper_methods)]
66
#![feature(cell_update)]
7+
#![feature(const_align_offset)]
78
#![feature(const_assume)]
89
#![feature(const_black_box)]
910
#![feature(const_bool_to_option)]

library/core/tests/ptr.rs

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,22 @@ fn align_offset_zst() {
358358
}
359359
}
360360

361+
#[test]
362+
fn align_offset_zst_const() {
363+
const {
364+
// For pointers of stride = 0, the pointer is already aligned or it cannot be aligned at
365+
// all, because no amount of elements will align the pointer.
366+
let mut p = 1;
367+
while p < 1024 {
368+
assert!(ptr::invalid::<()>(p).align_offset(p) == 0);
369+
if p != 1 {
370+
assert!(ptr::invalid::<()>(p + 1).align_offset(p) == !0);
371+
}
372+
p = (p + 1).next_power_of_two();
373+
}
374+
}
375+
}
376+
361377
#[test]
362378
fn align_offset_stride_one() {
363379
// For pointers of stride = 1, the pointer can always be aligned. The offset is equal to
@@ -379,6 +395,25 @@ fn align_offset_stride_one() {
379395
}
380396
}
381397

398+
#[test]
399+
fn align_offset_stride_one_const() {
400+
const {
401+
// For pointers of stride = 1, the pointer can always be aligned. The offset is equal to
402+
// number of bytes.
403+
let mut align = 1;
404+
while align < 1024 {
405+
let mut ptr = 1;
406+
while ptr < 2 * align {
407+
let expected = ptr % align;
408+
let offset = if expected == 0 { 0 } else { align - expected };
409+
assert!(ptr::invalid::<u8>(ptr).align_offset(align) == offset);
410+
ptr += 1;
411+
}
412+
align = (align + 1).next_power_of_two();
413+
}
414+
}
415+
}
416+
382417
#[test]
383418
fn align_offset_various_strides() {
384419
unsafe fn test_stride<T>(ptr: *const T, align: usize) -> bool {
@@ -455,6 +490,132 @@ fn align_offset_various_strides() {
455490
assert!(!x);
456491
}
457492

493+
#[test]
494+
fn align_offset_various_strides_const() {
495+
const unsafe fn test_stride<T>(ptr: *const T, numptr: usize, align: usize) {
496+
let mut expected = usize::MAX;
497+
// Naive but definitely correct way to find the *first* aligned element of stride::<T>.
498+
let mut el = 0;
499+
while el < align {
500+
if (numptr + el * ::std::mem::size_of::<T>()) % align == 0 {
501+
expected = el;
502+
break;
503+
}
504+
el += 1;
505+
}
506+
let got = ptr.align_offset(align);
507+
assert!(got == expected);
508+
}
509+
510+
// For pointers of stride != 1, we verify the algorithm against the naivest possible
511+
// implementation
512+
let mut align = 1;
513+
let limit = 1024;
514+
while align < limit {
515+
for ptr in 1usize..4 * align {
516+
unsafe {
517+
#[repr(packed)]
518+
struct A3(u16, u8);
519+
test_stride::<A3>(ptr::invalid::<A3>(ptr), ptr, align);
520+
521+
struct A4(u32);
522+
test_stride::<A4>(ptr::invalid::<A4>(ptr), ptr, align);
523+
524+
#[repr(packed)]
525+
struct A5(u32, u8);
526+
test_stride::<A5>(ptr::invalid::<A5>(ptr), ptr, align);
527+
528+
#[repr(packed)]
529+
struct A6(u32, u16);
530+
test_stride::<A6>(ptr::invalid::<A6>(ptr), ptr, align);
531+
532+
#[repr(packed)]
533+
struct A7(u32, u16, u8);
534+
test_stride::<A7>(ptr::invalid::<A7>(ptr), ptr, align);
535+
536+
#[repr(packed)]
537+
struct A8(u32, u32);
538+
test_stride::<A8>(ptr::invalid::<A8>(ptr), ptr, align);
539+
540+
#[repr(packed)]
541+
struct A9(u32, u32, u8);
542+
test_stride::<A9>(ptr::invalid::<A9>(ptr), ptr, align);
543+
544+
#[repr(packed)]
545+
struct A10(u32, u32, u16);
546+
test_stride::<A10>(ptr::invalid::<A10>(ptr), ptr, align);
547+
548+
test_stride::<u32>(ptr::invalid::<u32>(ptr), ptr, align);
549+
test_stride::<u128>(ptr::invalid::<u128>(ptr), ptr, align);
550+
}
551+
}
552+
align = (align + 1).next_power_of_two();
553+
}
554+
}
555+
556+
#[test]
557+
fn align_offset_with_provenance_const() {
558+
const {
559+
let data = 42;
560+
561+
let ptr: *const i32 = &data;
562+
assert!(ptr.align_offset(1) == 0);
563+
assert!(ptr.align_offset(2) == 0);
564+
assert!(ptr.align_offset(4) == 0);
565+
assert!(ptr.align_offset(8) == usize::MAX);
566+
assert!(ptr.wrapping_byte_add(1).align_offset(1) == 0);
567+
assert!(ptr.wrapping_byte_add(1).align_offset(2) == usize::MAX);
568+
assert!(ptr.wrapping_byte_add(2).align_offset(1) == 0);
569+
assert!(ptr.wrapping_byte_add(2).align_offset(2) == 0);
570+
assert!(ptr.wrapping_byte_add(2).align_offset(4) == usize::MAX);
571+
assert!(ptr.wrapping_byte_add(3).align_offset(1) == 0);
572+
assert!(ptr.wrapping_byte_add(3).align_offset(2) == usize::MAX);
573+
574+
assert!(ptr.wrapping_add(42).align_offset(4) == 0);
575+
assert!(ptr.wrapping_add(42).align_offset(8) == usize::MAX);
576+
577+
let ptr1: *const i8 = ptr.cast();
578+
assert!(ptr1.align_offset(1) == 0);
579+
assert!(ptr1.align_offset(2) == 0);
580+
assert!(ptr1.align_offset(4) == 0);
581+
assert!(ptr1.align_offset(8) == usize::MAX);
582+
assert!(ptr1.wrapping_byte_add(1).align_offset(1) == 0);
583+
assert!(ptr1.wrapping_byte_add(1).align_offset(2) == 1);
584+
assert!(ptr1.wrapping_byte_add(1).align_offset(4) == 3);
585+
assert!(ptr1.wrapping_byte_add(1).align_offset(8) == usize::MAX);
586+
assert!(ptr1.wrapping_byte_add(2).align_offset(1) == 0);
587+
assert!(ptr1.wrapping_byte_add(2).align_offset(2) == 0);
588+
assert!(ptr1.wrapping_byte_add(2).align_offset(4) == 2);
589+
assert!(ptr1.wrapping_byte_add(2).align_offset(8) == usize::MAX);
590+
assert!(ptr1.wrapping_byte_add(3).align_offset(1) == 0);
591+
assert!(ptr1.wrapping_byte_add(3).align_offset(2) == 1);
592+
assert!(ptr1.wrapping_byte_add(3).align_offset(4) == 1);
593+
assert!(ptr1.wrapping_byte_add(3).align_offset(8) == usize::MAX);
594+
595+
let ptr2: *const i16 = ptr.cast();
596+
assert!(ptr2.align_offset(1) == 0);
597+
assert!(ptr2.align_offset(2) == 0);
598+
assert!(ptr2.align_offset(4) == 0);
599+
assert!(ptr2.align_offset(8) == usize::MAX);
600+
assert!(ptr2.wrapping_byte_add(1).align_offset(1) == 0);
601+
assert!(ptr2.wrapping_byte_add(1).align_offset(2) == usize::MAX);
602+
assert!(ptr2.wrapping_byte_add(2).align_offset(1) == 0);
603+
assert!(ptr2.wrapping_byte_add(2).align_offset(2) == 0);
604+
assert!(ptr2.wrapping_byte_add(2).align_offset(4) == 1);
605+
assert!(ptr2.wrapping_byte_add(2).align_offset(8) == usize::MAX);
606+
assert!(ptr2.wrapping_byte_add(3).align_offset(1) == 0);
607+
assert!(ptr2.wrapping_byte_add(3).align_offset(2) == usize::MAX);
608+
609+
let ptr3: *const i64 = ptr.cast();
610+
assert!(ptr3.align_offset(1) == 0);
611+
assert!(ptr3.align_offset(2) == 0);
612+
assert!(ptr3.align_offset(4) == 0);
613+
assert!(ptr3.align_offset(8) == usize::MAX);
614+
assert!(ptr3.wrapping_byte_add(1).align_offset(1) == 0);
615+
assert!(ptr3.wrapping_byte_add(1).align_offset(2) == usize::MAX);
616+
}
617+
}
618+
458619
#[test]
459620
fn offset_from() {
460621
let mut a = [0; 5];

0 commit comments

Comments
 (0)