1// __NO_INLINE__ is defined so bsearch needs interceptor.
2// RUN: %clangxx_msan -fno-sanitize-memory-param-retval -O0 -g %s -o %t && %run %t
3// RUN: %clangxx_msan -fno-sanitize-memory-param-retval -DPOISON_DATA -O0 -g %s -o %t && not %run %t 2>&1 | FileCheck %s
4// RUN: %clangxx_msan -fno-sanitize-memory-param-retval -DPOISON_KEY -O0 -g %s -o %t && not %run %t 2>&1 | FileCheck %s
5
6// __NO_INLINE__ is undefined so bsearch should be inlined and instrumented and still work as expected.
7// RUN: %clangxx_msan -fno-sanitize-memory-param-retval -O2 -g %s -o %t && %run %t
8// RUN: %clangxx_msan -fno-sanitize-memory-param-retval -DPOISON_DATA -O2 -g %s -o %t && not %run %t 2>&1 | FileCheck %s
9// RUN: %clangxx_msan -fno-sanitize-memory-param-retval -DPOISON_KEY -O2 -g %s -o %t && not %run %t 2>&1 | FileCheck %s
10
11#include <assert.h>
12#include <stdlib.h>
13
14#include <sanitizer/msan_interface.h>
15
16long z;
17
18__attribute__((noinline, optnone)) void
19poison_msan_param_tls(long a, long b, long c, long d, long e, long f) {
20 z = a + b + c + d + e + f;
21}
22
23static int compar(const void *a, const void *b) {
24 int r = *(const long *)a - *(const long *)b;
25 long x;
26 __msan_poison(a: &x, size: sizeof(x));
27 poison_msan_param_tls(a: x, b: x, c: x, d: x, e: x, f: x);
28 return r;
29}
30
31int main(int argc, char *argv[]) {
32 constexpr size_t SZ = 27;
33 long p[SZ + 1];
34 for (int i = 0; i < SZ + 1; ++i)
35 p[i] = i;
36 p[SZ] = SZ / 3;
37#if defined(POISON_DATA)
38 __msan_poison(p, sizeof(long) * SZ / 2);
39#elif defined(POISON_KEY)
40 __msan_poison(p + SZ, sizeof(long));
41#endif
42 const long *r = (const long *)bsearch(key: p + SZ, base: p, nmemb: SZ, size: sizeof(long), compar: compar);
43 // CHECK: MemorySanitizer: use-of-uninitialized-value
44
45 assert(r == p + SZ / 3);
46
47 return 0;
48}
49

source code of compiler-rt/test/msan/bsearch.cpp