xref: /llvm-project/compiler-rt/test/nsan/stable_sort.cpp (revision d5617ada36705e871f329a7b0efb19ce6e6e2a1f)
1*d5617adaSAlexander Shaposhnikov // RUN: %clangxx_nsan -O2 -g %s -o %t
2*d5617adaSAlexander Shaposhnikov // RUN: %run %t 2>&1 | FileCheck %s
3*d5617adaSAlexander Shaposhnikov 
4*d5617adaSAlexander Shaposhnikov // Check compilation mode that is required to call memcpy/memmove.
5*d5617adaSAlexander Shaposhnikov // RUN: %clangxx_nsan -fno-builtin -O2 -g %s -o %t
6*d5617adaSAlexander Shaposhnikov // RUN: %run %t 2>&1 | FileCheck %s
7*d5617adaSAlexander Shaposhnikov 
8*d5617adaSAlexander Shaposhnikov // This tests a particularaly hard case of memory tracking. stable_sort does
9*d5617adaSAlexander Shaposhnikov // conditional swaps of pairs of elements with mixed types (int/double).
10*d5617adaSAlexander Shaposhnikov 
11*d5617adaSAlexander Shaposhnikov #include <algorithm>
12*d5617adaSAlexander Shaposhnikov #include <cstddef>
13*d5617adaSAlexander Shaposhnikov #include <cstdio>
14*d5617adaSAlexander Shaposhnikov #include <utility>
15*d5617adaSAlexander Shaposhnikov #include <vector>
16*d5617adaSAlexander Shaposhnikov 
17*d5617adaSAlexander Shaposhnikov extern "C" void __nsan_dump_shadow_mem(const char *addr, size_t size_bytes,
18*d5617adaSAlexander Shaposhnikov                                        size_t bytes_per_line, size_t reserved);
19*d5617adaSAlexander Shaposhnikov 
20*d5617adaSAlexander Shaposhnikov __attribute__((noinline)) void Run(std::vector<int> &indices,
21*d5617adaSAlexander Shaposhnikov                                    std::vector<double> &values) {
22*d5617adaSAlexander Shaposhnikov   const auto num_entries = indices.size();
23*d5617adaSAlexander Shaposhnikov   std::vector<std::pair<int, double>> entries;
24*d5617adaSAlexander Shaposhnikov   entries.reserve(num_entries);
25*d5617adaSAlexander Shaposhnikov   for (size_t i = 0; i < num_entries; ++i)
26*d5617adaSAlexander Shaposhnikov     entries.emplace_back(indices[i], values[i]);
27*d5617adaSAlexander Shaposhnikov 
28*d5617adaSAlexander Shaposhnikov   __nsan_dump_shadow_mem((const char *)&entries[0].second, sizeof(double),
29*d5617adaSAlexander Shaposhnikov                          sizeof(double), 0);
30*d5617adaSAlexander Shaposhnikov   __nsan_dump_shadow_mem((const char *)&entries[1].second, sizeof(double),
31*d5617adaSAlexander Shaposhnikov                          sizeof(double), 0);
32*d5617adaSAlexander Shaposhnikov   // CHECK: {{.*}}: d0 d1 d2 d3 d4 d5 d6 d7 (1.02800000000000002487)
33*d5617adaSAlexander Shaposhnikov   // CHECK-NEXT: {{.*}}: d0 d1 d2 d3 d4 d5 d6 d7 (7.95099999999999962341)
34*d5617adaSAlexander Shaposhnikov   std::stable_sort(
35*d5617adaSAlexander Shaposhnikov       entries.begin(), entries.end(),
36*d5617adaSAlexander Shaposhnikov       [](const std::pair<int, double> &a, const std::pair<int, double> &b) {
37*d5617adaSAlexander Shaposhnikov         return a.first < b.first;
38*d5617adaSAlexander Shaposhnikov       });
39*d5617adaSAlexander Shaposhnikov   __nsan_dump_shadow_mem((const char *)&entries[0].second, sizeof(double),
40*d5617adaSAlexander Shaposhnikov                          sizeof(double), 0);
41*d5617adaSAlexander Shaposhnikov   __nsan_dump_shadow_mem((const char *)&entries[1].second, sizeof(double),
42*d5617adaSAlexander Shaposhnikov                          sizeof(double), 0);
43*d5617adaSAlexander Shaposhnikov   // We make sure that the shadow values have been swapped correctly.
44*d5617adaSAlexander Shaposhnikov   // CHECK-NEXT: {{.*}}: d0 d1 d2 d3 d4 d5 d6 d7 (7.95099999999999962341)
45*d5617adaSAlexander Shaposhnikov   // CHECK-NEXT: {{.*}}: d0 d1 d2 d3 d4 d5 d6 d7 (1.02800000000000002487)
46*d5617adaSAlexander Shaposhnikov }
47*d5617adaSAlexander Shaposhnikov 
48*d5617adaSAlexander Shaposhnikov int main() {
49*d5617adaSAlexander Shaposhnikov   std::vector<int> indices;
50*d5617adaSAlexander Shaposhnikov   std::vector<double> values;
51*d5617adaSAlexander Shaposhnikov   indices.push_back(75);
52*d5617adaSAlexander Shaposhnikov   values.push_back(1.028);
53*d5617adaSAlexander Shaposhnikov   indices.push_back(74);
54*d5617adaSAlexander Shaposhnikov   values.push_back(7.951);
55*d5617adaSAlexander Shaposhnikov   Run(indices, values);
56*d5617adaSAlexander Shaposhnikov }
57