Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix assembling mutable slice from const reference #1358

Merged

Commits on Nov 12, 2020

  1. Fix assembling mutable slice from const reference

    The pointer from which a mutable reference is created must have
    provenance for accessing the underlying elements of the struct and its
    fields (a single array here) mutably. A pointer acquired by
    slice::as_ptr does not have that provenance, it only allows shared read
    access. The `slice::as_ptr` method says:
    
    > The caller must also ensure that the memory the pointer
    (non-transitively) points to is never written to (except inside an
    UnsafeCell) using this pointer or any pointer derived from it. If you
    need to mutate the contents of the slice, use as_mut_ptr.
    
    This fails MIRI which checks for this assertion but I'm not aware of
    mis-compilation resulting from it. In fact, consider:
    
        pub fn as_ptr(slice: &mut [u8]) -> *const u8 {
            slice.as_ptr()
        }
        pub fn as_mut_ptr(slice: &mut [u8]) -> *mut u8 {
            slice.as_mut_ptr()
        }
    
    <https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=28d3c19800236ae520441a22a6f99b19>
    
    Then llvm-IR in optimization will show that the functions are collapsed
    to a single one, hinting there is no semantic difference at that level.
    The difference in codegen is a readonly attribute on the slice::as_ptr
    argument but this is scoped to the particular function and argument, not
    the pointer value itself:
    
    > On a function, this attribute indicates that the function does not
    write through any pointer arguments
    <https://llvm.org/docs/LangRef.html>
    
    Since the _outer_ function correctly takes a `&mut self` argument the
    restriction possibly no longer applies to our own method. Of course, a
    stricter codegen of Rust's memory model might not be as kind and exploit
    the MIR level UB here.
    HeroicKatora committed Nov 12, 2020
    Copy the full SHA
    5cbe1e6 View commit details
    Browse the repository at this point in the history