Rollup merge of #118265 - RalfJung:memcpy, r=cuviper
remove the memcpy-on-equal-ptrs assumption One of the libc we support, musl, [defines `memcpy` with `restrict` pointers](https://git.musl-libc.org/cgit/musl/tree/src/string/memcpy.c#n5). This in fact matches the definition in the C standard. Calling that `memcpy` with overlapping pointers is clearly UB, who knows what the compiler did when optimizing this `memcpy` -- it certainly assumed source and destination to be disjoint. Lucky enough, it does not seem like we actually need this assumption that `memcpy(p, p, n)` is always allowed. clang and GCC need it since they use `memcpy` to compile C assignments, but [we use memmove for similar code](https://godbolt.org/z/bcW85WYcM). There are no known cases where LLVM introduces calls to memcpy on equal pointers itself. (And if there were, that would be a soundness bug in rustc due to the musl issue mentioned above.) This does mean we must make sure to never call the LLVM `memcpy` builtin on equal ranges even though the LangRef says that is allowed. Currently that is the case so we just need to make sure it remains the case. :) Cc `@rust-lang/opsem` `@rust-lang/wg-llvm`
This commit is contained in:
commit
92a74e41b6
@ -24,9 +24,8 @@
|
|||||||
//! which are generated by Rust codegen backends. Additionally, this library can make explicit
|
//! which are generated by Rust codegen backends. Additionally, this library can make explicit
|
||||||
//! calls to `strlen`. Their signatures are the same as found in C, but there are extra
|
//! calls to `strlen`. Their signatures are the same as found in C, but there are extra
|
||||||
//! assumptions about their semantics: For `memcpy`, `memmove`, `memset`, `memcmp`, and `bcmp`, if
|
//! assumptions about their semantics: For `memcpy`, `memmove`, `memset`, `memcmp`, and `bcmp`, if
|
||||||
//! the `n` parameter is 0, the function is assumed to not be UB. Furthermore, for `memcpy`, if
|
//! the `n` parameter is 0, the function is assumed to not be UB, even if the pointers are NULL or
|
||||||
//! source and target pointer are equal, the function is assumed to not be UB.
|
//! dangling. (Note that making extra assumptions about these functions is common among compilers:
|
||||||
//! (Note that these are standard assumptions among compilers:
|
|
||||||
//! [clang](https://reviews.llvm.org/D86993) and [GCC](https://gcc.gnu.org/onlinedocs/gcc/Standards.html#C-Language) do the same.)
|
//! [clang](https://reviews.llvm.org/D86993) and [GCC](https://gcc.gnu.org/onlinedocs/gcc/Standards.html#C-Language) do the same.)
|
||||||
//! These functions are often provided by the system libc, but can also be provided by the
|
//! These functions are often provided by the system libc, but can also be provided by the
|
||||||
//! [compiler-builtins crate](https://crates.io/crates/compiler_builtins).
|
//! [compiler-builtins crate](https://crates.io/crates/compiler_builtins).
|
||||||
|
Loading…
Reference in New Issue
Block a user