Skip to content

ptr::read and ptr::write (and others?) should specify alignment requirements in their contract #36450

Closed

Description

@whitequark

Currently, these functions do not say anything about whether the raw pointer has to be aligned. They are also currently implemented with copy_nonoverlapping, which means they are safe to use with unaligned data. However, @ubsan tells me that this is an implementation detail that cannot be relied on.

In any case, these functions should explicitly specify their alignment requirements. Similarly, ptr::copy{,_nonoverlapping} also should do that, since right now they do not explicitly state that in their contract either. (They do reference C's memcpy and memmove, but I don't think that a C reference is a good way to define normative semantics.)

Activity

  1. strega-nil commented on Sep 13, 2016

    @strega-nil
    Contributor
  2. Amanieu commented on Sep 13, 2016

    @Amanieu
    Member
  3. Amanieu commented on Sep 13, 2016

    @Amanieu
    Member

    Also keep in mind that copy(_nonoverlapping) does have alignment requirements: it's based on the type of the pointer. So if you pass a *mut u32 to copy_nonoverlapping then LLVM will assume that the pointer is aligned to 4 bytes.

  4. whitequark commented on Sep 13, 2016

    @whitequark
    ContributorAuthor

    That then should be explicitly specified also, because it is definitely not a part of the C memcpy semantics.

  5. bluss commented on Sep 14, 2016

    @bluss
    Contributor

    Maybe it's obvious in this discussion, but *ptr (copy to value from raw pointer) requires ptr to be aligned, of course. With that as the baseline, I think it would have to be assumed that read/write use that rule if nothing else is documented -- but why not document it explicitly.

  6. strega-nil commented on Sep 14, 2016

    @strega-nil
    Contributor

    @bluss That's also never documented, to be clear, except in the not-right-places in the nomicon.

  7. tbu- commented on Mar 7, 2017

    @tbu-
    Contributor

    Seems to be fixed, the documentation says:

    The pointer must be aligned; use write_unaligned if that is not the case.

    and similarly for ptr::read.

  8. strega-nil commented on Mar 8, 2017

    @strega-nil
    Contributor

    Recommend closing as fixed.

  9. whitequark commented on Mar 8, 2017

    @whitequark
    ContributorAuthor

    copy{,_nonoverlapping} don't have mention of alignment in the documentation still.

  10. arielb1 commented on Mar 8, 2017

    @arielb1
    Contributor

    @whitequark

    That's because it has none.

  11. whitequark commented on Mar 8, 2017

    @whitequark
    ContributorAuthor

    Also keep in mind that copy(_nonoverlapping) does have alignment requirements: it's based on the type of the pointer. So if you pass a *mut u32 to copy_nonoverlapping then LLVM will assume that the pointer is aligned to 4 bytes.

    @Amanieu above disagrees...

  12. tbu- commented on Mar 8, 2017

    @tbu-
    Contributor

    The linked RFC (by @Amanieu) states that it uses copy_nonoverlapping for {read,write}_unaligned.

  13. arielb1 commented on Mar 8, 2017

    @arielb1
    Contributor

    @whitequark

    I had the mistaken impression that copy_nonoverlapping took a u8 parameter.

  14. reopened this on Mar 8, 2017
  15. Mark-Simulacrum commented on May 27, 2017

    @Mark-Simulacrum
    Member

    Okay, so this appears to be a documentation issue -- we need to update ptr::copy{,_nonoverlapping} to state something about alignment.

  16. added
    A-docsArea: Documentation for any part of the project, including the compiler, standard library, and tools
    on May 27, 2017
  17. QuietMisdreavus commented on Sep 13, 2017

    @QuietMisdreavus
    Contributor

    The docs team discussed this today. Here's the current state of the ptr module, with respect to alignment:

    <ubsan> because anything in the standard library which takes a raw pointer assumes validity of the
            raw pointer, unless it's explicitly denoted `_unaligned`, in which case size must be valid,
            but alignment might not be
    (...)
    <ubsan> copy{_nonoverlapping}, read_volatile, probably replace, probably swap (uses "valid",
            probably could be more wordy), write_volatile, swap_nonoverlapping
    <ubsan> we should also standardize this documentation across all of the functions
    (...)
    <ubsan> (some put their requirements under "Safety", some put it under "Undefined Behavior", etc.)
    

    Basically, to really close this issue it would be prudent to go over every function in ptr and leave a note about the assumed alignment requirements of it.

    Since #29371 is still open, i'm considering this issue part of that one.

  18. added
    E-mediumCall for participation: Medium difficulty. Experience needed to fix: Intermediate.
    on May 28, 2018
  19. ecstatic-morse commented on Feb 6, 2019

    @ecstatic-morse
    Contributor

    @steveklabnik. This was completed in #53783. All functions in std::ptr now state their alignment requirements in the "Safety" section.

  20. steveklabnik commented on Feb 6, 2019

    @steveklabnik
    Contributor

    Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-docsArea: Documentation for any part of the project, including the compiler, standard library, and toolsC-enhancementCategory: An issue proposing an enhancement or a PR with one.E-mediumCall for participation: Medium difficulty. Experience needed to fix: Intermediate.P-lowLow priority

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions