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
13constexpr size_t kSize1 = 27;
14constexpr size_t kSize2 = 7;
15
16bool seen2;
17
18void dummy(long a, long b, long c, long d, long e) {}
19
20void poison_stack_and_param() {
21 char x[10000];
22 int y;
23 dummy(a: y, b: y, c: y, d: y, e: 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
35int compar2(const void *a, const void *b) {
36 assert(a);
37 assert(b);
38 __msan_check_mem_is_initialized(x: a, size: sizeof(long));
39 __msan_check_mem_is_initialized(x: b, size: sizeof(long));
40 seen2 = true;
41 poison_stack_and_param();
42 return cmp(a: *(long *)a, b: *(long *)b);
43}
44
45int compar1(const void *a, const void *b) {
46 assert(a);
47 assert(b);
48 __msan_check_mem_is_initialized(x: a, size: sizeof(long));
49 __msan_check_mem_is_initialized(x: b, size: 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(base: p, nmemb: kSize1, size: sizeof(long), compar: compar2);
56 __msan_check_mem_is_initialized(x: p, size: sizeof(long) * kSize2);
57 delete[] p;
58
59 poison_stack_and_param();
60 return cmp(a: *(long *)a, b: *(long *)b);
61}
62
63int 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(base: p, nmemb: kSize1, size: sizeof(long), compar: compar1);
74 __msan_check_mem_is_initialized(x: p, size: sizeof(long) * kSize1);
75 assert(seen2);
76 delete[] p;
77
78 p = new long[0];
79 qsort(base: p, nmemb: 0, size: sizeof(long), compar: compar1);
80 delete[] p;
81
82 qsort(base: nullptr, nmemb: 0, size: sizeof(long), compar: compar1);
83
84 return 0;
85}
86

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