Ralf Jung via llvm-dev
2017-Jul-20 21:35 UTC
[llvm-dev] Which assumptions do llvm.memcpy/memmove/memset.* make when the count is 0?
Hi all, when I call the llvm.memcpy/memmove/memset.* intrinsics, typically I have to pass in valid (non-dangling, non-NULL pointers) of the given alignment. However, to what extent to these rules apply when the count is 0? Concretely (for any variant of the three aforementioned intrinsics): Is it UB to call them on a dangling pointer when count is 0? On a pointer of less than the given alignment? The actual operation will of course not do anything, but I am worried about some analysis seeing a pointer being used as an argument to one of these intrinsics, and then assuming the pointer is valid and aligned without proving that the count is > 0. E.g., Rust's HashMap indirectly calls memset(0x0, 0, 0, ..., false). Vec calls memcpy(..., 0x1, 0, 4, false). Is that a problem? Kind regards, Ralf PS: I'm not on the list, so please keep me in Cc.
Jeremy Lakeman via llvm-dev
2017-Jul-21 03:46 UTC
[llvm-dev] Which assumptions do llvm.memcpy/memmove/memset.* make when the count is 0?
>From https://www.quora.com/Is-memcpy-0-0-0-undefined-behaviour-in-CYes, the C standard explicitly addresses this in §7.24.1/2, which applies to memcpy and all other functions from string.h Where an argument declared as size_t n specifies the length of the array for a function, n can have the value zero on a call to that function. Unless explicitly stated otherwise in the description of a particular function in this subclause, pointer arguments on such a call shall still have valid values, as described in 7.1.4. On such a call, a function that locates a character finds no occurrence, a function that compares two character sequences returns zero, and a function that copies characters copies zero characters The description of memcpy in §7.24.1.2 does not "explicitly state otherwise", and §7.1.4 defines invalid pointer as a pointer outside the address space of the program, or a null pointer, or a pointer to non-modifiable storage when the corresponding parameter is not const-qualified So, the pointer arguments of memcpy *shall* (a violation of a shall clause is UB, per §4/2) have valid values, even though the function will copy zero characters. On Fri, Jul 21, 2017 at 7:05 AM, Ralf Jung via llvm-dev < llvm-dev at lists.llvm.org> wrote:> Hi all, > > when I call the llvm.memcpy/memmove/memset.* intrinsics, typically I > have to pass in valid (non-dangling, non-NULL pointers) of the given > alignment. However, to what extent to these rules apply when the count > is 0? Concretely (for any variant of the three aforementioned > intrinsics): Is it UB to call them on a dangling pointer when count is > 0? On a pointer of less than the given alignment? > > The actual operation will of course not do anything, but I am worried > about some analysis seeing a pointer being used as an argument to one of > these intrinsics, and then assuming the pointer is valid and aligned > without proving that the count is > 0. > > E.g., Rust's HashMap indirectly calls memset(0x0, 0, 0, ..., false). > Vec calls memcpy(..., 0x1, 0, 4, false). Is that a problem? > > Kind regards, > Ralf > > PS: I'm not on the list, so please keep me in Cc. > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170721/4e6cd5e0/attachment.html>
John Regehr via llvm-dev
2017-Jul-21 04:00 UTC
[llvm-dev] Which assumptions do llvm.memcpy/memmove/memset.* make when the count is 0?
> So, the pointer arguments of memcpy *shall* (a violation of a shall > clause is UB, per §4/2) have valid values, even though the function will > copy zero characters.This is true in C but the question was about LLVM intrinsics. Since the LangRef does not mention any such restriction, I would assume that memcpy(0,0,0) is not UB in LLVM. If it is UB then we must update the LangRef to be clear on this point (actually we should update the LangRef either way since this is a question that'll come up again). John
Maybe Matching Threads
- Which assumptions do llvm.memcpy/memmove/memset.* make when the count is 0?
- Which assumptions do llvm.memcpy/memmove/memset.* make when the count is 0?
- Which assumptions do llvm.memcpy/memmove/memset.* make when the count is 0?
- Which assumptions do llvm.memcpy/memmove/memset.* make when the count is 0?
- The semantics of nonnull attribute