1 // RUN: %clangxx_msan -O0 -g %s -o %t && %run %t 2 // RUN: %clangxx_msan -DPOISON -O0 -g %s -o %t && not %run %t 2>&1 | FileCheck %s 3 4 #include <assert.h> 5 #include <errno.h> 6 #include <glob.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <string.h> 10 11 #include <sanitizer/msan_interface.h> 12 13 constexpr size_t kSize1 = 27; 14 constexpr size_t kSize2 = 7; 15 16 bool seen2; 17 18 void dummy(long a, long b, long c, long d, long e) {} 19 20 void poison_stack_and_param() { 21 char x[10000]; 22 int y; 23 dummy(y, y, y, y, y); 24 } 25 26 __attribute__((always_inline)) int cmp(long a, long b) { 27 if (a < b) 28 return -1; 29 else if (a > b) 30 return 1; 31 else 32 return 0; 33 } 34 35 int compar2(const void *a, const void *b) { 36 assert(a); 37 assert(b); 38 __msan_check_mem_is_initialized(a, sizeof(long)); 39 __msan_check_mem_is_initialized(b, sizeof(long)); 40 seen2 = true; 41 poison_stack_and_param(); 42 return cmp(*(long *)a, *(long *)b); 43 } 44 45 int compar1(const void *a, const void *b) { 46 assert(a); 47 assert(b); 48 __msan_check_mem_is_initialized(a, sizeof(long)); 49 __msan_check_mem_is_initialized(b, sizeof(long)); 50 51 long *p = new long[kSize2]; 52 // kind of random 53 for (int i = 0; i < kSize2; ++i) 54 p[i] = i * 2 + (i % 3 - 1) * 3; 55 qsort(p, kSize1, sizeof(long), compar2); 56 __msan_check_mem_is_initialized(p, sizeof(long) * kSize2); 57 delete[] p; 58 59 poison_stack_and_param(); 60 return cmp(*(long *)a, *(long *)b); 61 } 62 63 int main(int argc, char *argv[]) { 64 long *p = new long[kSize1]; 65 // kind of random 66 for (int i = 0; i < kSize1; ++i) 67 p[i] = i * 2 + (i % 3 - 1) * 3; 68 poison_stack_and_param(); 69 #ifdef POISON 70 __msan_poison(p + 1, sizeof(long)); 71 // CHECK: Uninitialized bytes in __msan_check_mem_is_initialized at offset 0 inside [{{.*}}, 8) 72 #endif 73 qsort(p, kSize1, sizeof(long), compar1); 74 __msan_check_mem_is_initialized(p, sizeof(long) * kSize1); 75 assert(seen2); 76 delete[] p; 77 78 p = new long[0]; 79 qsort(p, 0, sizeof(long), compar1); 80 delete[] p; 81 82 qsort(nullptr, 0, sizeof(long), compar1); 83 84 return 0; 85 } 86