Opened 4 years ago

Last modified 2 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 4 years ago by mornfall

Owner: set to mornfall
Status: newaccepted

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).

comment:2 Changed 2 years ago by Dávid Bolvanský

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.

Note: See TracTickets for help on using tickets.