Opened 5 years ago
Last modified 3 years ago
#87 accepted defect
Struct self-assignment results in assertion failure in memcpy
Reported by: | Lukáš Zaoral | Owned by: | mornfall |
---|---|---|---|
Priority: | major | Milestone: | 4.3 |
Component: | DiOS | Keywords: | |
Cc: | kdudka@…, jamartis@…, lzaoral@…, Dávid Bolvanský |
Description
Hi,
the following code makes Divine 4.3.6 crash with an assertion failure in the DiOS's implementation of memcpy
. While it is true, that the memory passed to memcpy
should not overlap, the struct
self-assignment should be permitted.
Thanks.
int main(void) { struct { char a; int i; } s; s = s; }
Change History (2)
comment:1 Changed 5 years ago by
Owner: | set to mornfall |
---|---|
Status: | new → accepted |
comment:2 Changed 3 years ago by
Cc: | Dávid Bolvanský added |
---|
Related discussion:
https://lists.llvm.org/pipermail/llvm-dev/2020-August/144599.html
LLVM Langref
The ‘llvm.memcpy.*’ intrinsics copy a block of memory from the source location to the destination location, which must either be *equal* or non-overlapping. It copies “len” bytes of memory over. If the argument is known to be aligned to some boundary, this can be specified as an attribute on the argument.
"There is a longstanding assumption made by ~every compiler that memcpy(p, p, n) is safe."
dios libc memcpy implementation looks fine (to support this edge case) so I would propose to remove/adjust this strong assert.
That's interesting, because this looks like the code generated by clang/llvm is wrong. I will investigate, but clang usually emits an intrinsic version of 'memcpy' which on many/most architectures is replaced with specialized native code directly by the codegen. But the llvm-builtin fallback is to call 'memcpy' (we do no such replacement in our code as far as I can tell).