Files
clang-p2996/compiler-rt/test/msan/bsearch.cpp
Vitaly Buka 9ab590e3eb [msan] Add bsearch interceptor
Similar to qsort, bsearch can be called from non-instrumented
code of glibc. When it happends tls for arguments can be in uninitialized
state.

Unlike to qsort, bsearch does not move data, so we don't need to
check or initialize searched memory or key. Intrumented comparator will
do that on it's own.

Differential Revision: https://reviews.llvm.org/D107387
2021-08-03 18:39:14 -07:00

49 lines
1.5 KiB
C++

// __NO_INLINE__ is defined so bsearch needs interceptor.
// RUN: %clangxx_msan -O0 -g %s -o %t && %run %t
// RUN: %clangxx_msan -DPOISON_DATA -O0 -g %s -o %t && not %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_msan -DPOISON_KEY -O0 -g %s -o %t && not %run %t 2>&1 | FileCheck %s
// __NO_INLINE__ is undefined so bsearch should be inlined and instrumented and still work as expected.
// RUN: %clangxx_msan -O2 -g %s -o %t && %run %t
// RUN: %clangxx_msan -DPOISON_DATA -O2 -g %s -o %t && not %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_msan -DPOISON_KEY -O2 -g %s -o %t && not %run %t 2>&1 | FileCheck %s
#include <assert.h>
#include <stdlib.h>
#include <sanitizer/msan_interface.h>
long z;
__attribute__((noinline, optnone)) void
poison_msan_param_tls(long a, long b, long c, long d, long e, long f) {
z = a + b + c + d + e + f;
}
static int compar(const void *a, const void *b) {
int r = *(const long *)a - *(const long *)b;
long x;
__msan_poison(&x, sizeof(x));
poison_msan_param_tls(x, x, x, x, x, x);
return r;
}
int main(int argc, char *argv[]) {
constexpr size_t SZ = 27;
long p[SZ + 1];
for (int i = 0; i < SZ + 1; ++i)
p[i] = i;
p[SZ] = SZ / 3;
#if defined(POISON_DATA)
__msan_poison(p, sizeof(long) * SZ / 2);
#elif defined(POISON_KEY)
__msan_poison(p + SZ, sizeof(long));
#endif
const long *r = (const long *)bsearch(p + SZ, p, SZ, sizeof(long), compar);
// CHECK: MemorySanitizer: use-of-uninitialized-value
assert(r == p + SZ / 3);
return 0;
}