Opened 6 years ago
Last modified 4 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 6 years ago by
| Owner: | set to mornfall |
|---|---|
| Status: | new → accepted |
comment:2 Changed 4 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).