xref: /llvm-project/compiler-rt/test/msan/qsort.cpp (revision 15805c030f31b8d112ee4a4706ff4f5725c794df)
1 // RUN: %clangxx_msan -fno-sanitize-memory-param-retval -O0 -g %s -o %t && %run %t
2 // RUN: %clangxx_msan -fno-sanitize-memory-param-retval -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 
dummy(long a,long b,long c,long d,long e)18 void dummy(long a, long b, long c, long d, long e) {}
19 
poison_stack_and_param()20 void poison_stack_and_param() {
21   char x[10000];
22   int y;
23   dummy(y, y, y, y, y);
24 }
25 
cmp(long a,long b)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 
compar2(const void * a,const void * b)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 
compar1(const void * a,const void * b)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 
main(int argc,char * argv[])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