1 // __NO_INLINE__ is defined so bsearch needs interceptor. 2 // RUN: %clangxx_msan -O0 -g %s -o %t && %run %t 3 // RUN: %clangxx_msan -DPOISON_DATA -O0 -g %s -o %t && not %run %t 2>&1 | FileCheck %s 4 // RUN: %clangxx_msan -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 -O2 -g %s -o %t && %run %t 8 // RUN: %clangxx_msan -DPOISON_DATA -O2 -g %s -o %t && not %run %t 2>&1 | FileCheck %s 9 // RUN: %clangxx_msan -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 16 long z; 17 18 __attribute__((noinline, optnone)) void 19 poison_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 23 static int compar(const void *a, const void *b) { 24 int r = *(const long *)a - *(const long *)b; 25 long x; 26 __msan_poison(&x, sizeof(x)); 27 poison_msan_param_tls(x, x, x, x, x, x); 28 return r; 29 } 30 31 int 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(p + SZ, p, SZ, sizeof(long), compar); 43 // CHECK: MemorySanitizer: use-of-uninitialized-value 44 45 assert(r == p + SZ / 3); 46 47 return 0; 48 } 49