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