llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.11k stars 11.61k forks source link

[analyzer] FP "uninitialized read" with hand-written memcpy #109836

Open pskrgag opened 3 hours ago

pskrgag commented 3 hours ago

ExprEngine now binds only to offset 0 in case of inline assembly input. This causes false-positive uninitialized read reports in following case:

(snippet adapted from real code base)

void *MyMemcpy(void *d, const void *s, const int n) {
  asm volatile (
    "cld\n rep movsb\n"
    :: "S" (s), "D" (d), "c" (n) : "memory"
  );
  return d;
}

void proccess(const void *src, unsigned long len)
{
    int a[10], c;
    unsigned long toCopy = sizeof(a) < len ? sizeof(a) : len;

    MyMemcpy(a, src, toCopy);

    for (unsigned long i = 0; i < toCopy; ++i)
      c = a[i]; // warning here on index > 0
}

(see example on godbolt https://godbolt.org/z/1e7E1cM7P).

llvmbot commented 3 hours ago

@llvm/issue-subscribers-clang-static-analyzer

Author: Pavel Skripkin (pskrgag)

ExprEngine now binds only to offset 0 in case of inline assembly input. This causes false-positive uninitialized read reports in following case: (snippet adapted from real code base) ```c void *MyMemcpy(void *d, const void *s, const int n) { asm volatile ( "cld\n rep movsb\n" :: "S" (s), "D" (d), "c" (n) : "memory" ); return d; } void proccess(const void *src, unsigned long len) { int a[10], c; unsigned long toCopy = sizeof(a) < len ? sizeof(a) : len; MyMemcpy(a, src, toCopy); for (unsigned long i = 0; i < toCopy; ++i) c = a[i]; // warning here on index > 0 } ``` (see example on godbolt https://godbolt.org/z/1e7E1cM7P).
pskrgag commented 3 hours ago

created an issue just to not flood pr message with code examples