<commit_before>#![feature(allocator_api)]

use std::ptr::NonNull;
use std::alloc::{Global, Alloc, Layout, System};
use std::slice;

fn check_alloc<T: Alloc>(mut allocator: T) { unsafe {
    let layout = Layout::from_size_align(20, 4).unwrap();
    let a = allocator.alloc(layout).unwrap();
    allocator.dealloc(a, layout);

    let p1 = allocator.alloc_zeroed(layout).unwrap();

    let p2 = allocator.realloc(p1, Layout::from_size_align(20, 4).unwrap(), 40).unwrap();
    let slice = slice::from_raw_parts(p2.as_ptr(), 20);
    assert_eq!(&slice, &[0_u8; 20]);

    // old size == new size
    let p3 = allocator.realloc(p2, Layout::from_size_align(40, 4).unwrap(), 40).unwrap();
    let slice = slice::from_raw_parts(p3.as_ptr(), 20);
    assert_eq!(&slice, &[0_u8; 20]);

    // old size > new size
    let p4 = allocator.realloc(p3, Layout::from_size_align(40, 4).unwrap(), 10).unwrap();
    let slice = slice::from_raw_parts(p4.as_ptr(), 10);
    assert_eq!(&slice, &[0_u8; 10]);

    allocator.dealloc(p4, Layout::from_size_align(10, 4).unwrap());
} }

fn check_overalign_requests<T: Alloc>(mut allocator: T) {
    let size = 8;
    // Greater than `size`.
    let align = 16;
    // Miri is deterministic; no need to try many times.
    let iterations = 1;
    unsafe {
        let pointers: Vec<_> = (0..iterations).map(|_| {
            allocator.alloc(Layout::from_size_align(size, align).unwrap()).unwrap()
        }).collect();
        for &ptr in &pointers {
            assert_eq!((ptr.as_ptr() as usize) % align, 0,
                       "Got a pointer less aligned than requested")
        }

        // Clean up.
        for &ptr in &pointers {
            allocator.dealloc(ptr, Layout::from_size_align(size, align).unwrap())
        }
    }
}

fn global_to_box() {
    type T = [i32; 4];
    let l = Layout::new::<T>();
    // allocate manually with global allocator, then turn into Box and free there
    unsafe {
        let ptr = Global.alloc(l).unwrap().as_ptr() as *mut T;
        let b = Box::from_raw(ptr);
        drop(b);
    }
}

fn box_to_global() {
    type T = [i32; 4];
    let l = Layout::new::<T>();
    // allocate with the Box, then deallocate manually with global allocator
    unsafe {
        let b = Box::new(T::default());
        let ptr = Box::into_raw(b);
        Global.dealloc(NonNull::new(ptr as *mut u8).unwrap(), l);
    }
}

fn main() {
    check_alloc(System);
    check_alloc(Global);
    #[cfg(not(target_os = "windows"))] // TODO: Inspects allocation base address on Windows; needs intptrcast model
    check_overalign_requests(System);
    check_overalign_requests(Global);
    global_to_box();
    box_to_global();
}
<commit_msg>use intptrcast for heap_allocator test; then it should work on Windows<commit_after>// compile-flag: -Zmiri-seed=
#![feature(allocator_api)]

use std::ptr::NonNull;
use std::alloc::{Global, Alloc, Layout, System};
use std::slice;

fn check_alloc<T: Alloc>(mut allocator: T) { unsafe {
    let layout = Layout::from_size_align(20, 4).unwrap();
    let a = allocator.alloc(layout).unwrap();
    allocator.dealloc(a, layout);

    let p1 = allocator.alloc_zeroed(layout).unwrap();

    let p2 = allocator.realloc(p1, Layout::from_size_align(20, 4).unwrap(), 40).unwrap();
    let slice = slice::from_raw_parts(p2.as_ptr(), 20);
    assert_eq!(&slice, &[0_u8; 20]);

    // old size == new size
    let p3 = allocator.realloc(p2, Layout::from_size_align(40, 4).unwrap(), 40).unwrap();
    let slice = slice::from_raw_parts(p3.as_ptr(), 20);
    assert_eq!(&slice, &[0_u8; 20]);

    // old size > new size
    let p4 = allocator.realloc(p3, Layout::from_size_align(40, 4).unwrap(), 10).unwrap();
    let slice = slice::from_raw_parts(p4.as_ptr(), 10);
    assert_eq!(&slice, &[0_u8; 10]);

    allocator.dealloc(p4, Layout::from_size_align(10, 4).unwrap());
} }

fn check_overalign_requests<T: Alloc>(mut allocator: T) {
    let size = 8;
    // Greater than `size`.
    let align = 16;
    // Miri is deterministic; no need to try many times.
    let iterations = 1;
    unsafe {
        let pointers: Vec<_> = (0..iterations).map(|_| {
            allocator.alloc(Layout::from_size_align(size, align).unwrap()).unwrap()
        }).collect();
        for &ptr in &pointers {
            assert_eq!((ptr.as_ptr() as usize) % align, 0,
                       "Got a pointer less aligned than requested")
        }

        // Clean up.
        for &ptr in &pointers {
            allocator.dealloc(ptr, Layout::from_size_align(size, align).unwrap())
        }
    }
}

fn global_to_box() {
    type T = [i32; 4];
    let l = Layout::new::<T>();
    // allocate manually with global allocator, then turn into Box and free there
    unsafe {
        let ptr = Global.alloc(l).unwrap().as_ptr() as *mut T;
        let b = Box::from_raw(ptr);
        drop(b);
    }
}

fn box_to_global() {
    type T = [i32; 4];
    let l = Layout::new::<T>();
    // allocate with the Box, then deallocate manually with global allocator
    unsafe {
        let b = Box::new(T::default());
        let ptr = Box::into_raw(b);
        Global.dealloc(NonNull::new(ptr as *mut u8).unwrap(), l);
    }
}

fn main() {
    check_alloc(System);
    check_alloc(Global);
    check_overalign_requests(System);
    check_overalign_requests(Global);
    global_to_box();
    box_to_global();
}

{'fraction_non_alphanumeric': 0.1597157284458575, 'fraction_numerical': 0.02356461567233963, 'mean_word_length': 3.0240782543265614, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4870646', 'n_tokens_mistral': 1908, 'n_tokens_neox': 1850, 'n_words': 441}