[compiler-rt] [compiler-rt][nsan] Add more tests for shadow memory (PR #100906)

via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 27 16:08:22 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-compiler-rt-sanitizer

Author: Alexander Shaposhnikov (alexander-shaposhnikov)

<details>
<summary>Changes</summary>

Add more tests for shadow memory.

---
Full diff: https://github.com/llvm/llvm-project/pull/100906.diff


2 Files Affected:

- (added) compiler-rt/test/nsan/stable_sort.cpp (+55) 
- (added) compiler-rt/test/nsan/swap.cpp (+46) 


``````````diff
diff --git a/compiler-rt/test/nsan/stable_sort.cpp b/compiler-rt/test/nsan/stable_sort.cpp
new file mode 100644
index 0000000000000..db839d32121fd
--- /dev/null
+++ b/compiler-rt/test/nsan/stable_sort.cpp
@@ -0,0 +1,55 @@
+// RUN: %clangxx_nsan -O2 -g %s -o %t
+// RUN: %run %t 2>&1 | FileCheck %s
+
+// RUN: %clangxx_nsan  -fno-builtin -O2 -g %s -o %t
+// RUN: %run %t 2>&1 | FileCheck %s
+
+// This tests a particularaly hard case of memory tracking. stable_sort does
+// conditional swaps of pairs of elements with mixed types (int/double).
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdio>
+#include <utility>
+#include <vector>
+
+extern "C" void __nsan_dump_shadow_mem(const char *addr, size_t size_bytes,
+                                       size_t bytes_per_line, size_t reserved);
+
+__attribute__((noinline)) void Run(std::vector<int> &indices,
+                                   std::vector<double> &values) {
+  const auto num_entries = indices.size();
+  std::vector<std::pair<int, double>> entries;
+  entries.reserve(num_entries);
+  for (int i = 0; i < num_entries; ++i) {
+    entries.emplace_back(indices[i], values[i]);
+  }
+  __nsan_dump_shadow_mem((const char *)&entries[0].second, sizeof(double),
+                         sizeof(double), 0);
+  __nsan_dump_shadow_mem((const char *)&entries[1].second, sizeof(double),
+                         sizeof(double), 0);
+  // CHECK: {{.*}}: d0 d1 d2 d3 d4 d5 d6 d7 (1.02800000000000002487)
+  // CHECK-NEXT: {{.*}}: d0 d1 d2 d3 d4 d5 d6 d7 (7.95099999999999962341)
+  std::stable_sort(
+      entries.begin(), entries.end(),
+      [](const std::pair<int, double> &a, const std::pair<int, double> &b) {
+        return a.first < b.first;
+      });
+  __nsan_dump_shadow_mem((const char *)&entries[0].second, sizeof(double),
+                         sizeof(double), 0);
+  __nsan_dump_shadow_mem((const char *)&entries[1].second, sizeof(double),
+                         sizeof(double), 0);
+  // We make sure that the shadow values have been swapped correctly.
+  // CHECK-NEXT: {{.*}}: d0 d1 d2 d3 d4 d5 d6 d7 (7.95099999999999962341)
+  // CHECK-NEXT: {{.*}}: d0 d1 d2 d3 d4 d5 d6 d7 (1.02800000000000002487)
+}
+
+int main() {
+  std::vector<int> indices;
+  std::vector<double> values;
+  indices.push_back(75);
+  values.push_back(1.028);
+  indices.push_back(74);
+  values.push_back(7.951);
+  Run(indices, values);
+}
diff --git a/compiler-rt/test/nsan/swap.cpp b/compiler-rt/test/nsan/swap.cpp
new file mode 100644
index 0000000000000..c42c52356e625
--- /dev/null
+++ b/compiler-rt/test/nsan/swap.cpp
@@ -0,0 +1,46 @@
+// RUN: %clangxx_nsan -O2 %s -o %t
+// RUN: %run %t 2>&1 | FileCheck %s
+
+// RUN: %clangxx_nsan -fno-builtin -O2 %s -o %t
+// RUN: %run %t 2>&1 | FileCheck %s
+
+// This verifies that shadow memory is tracked correcty across typed and
+// bitcasted swaps.
+
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <utility>
+
+extern "C" void __nsan_dump_shadow_mem(const char *addr, size_t size_bytes,
+                                       size_t bytes_per_line, size_t reserved);
+
+__attribute__((noinline)) void SwapFT(double *a, double *b) {
+  // LLVM typically optimizes this to an untyped swap (through i64) anyway.
+  std::swap(*a, *b);
+}
+
+__attribute__((noinline)) void SwapBitcasted(uint64_t *a, uint64_t *b) {
+  std::swap(*a, *b);
+}
+
+int main() {
+  double a = 1.0, b = 2.0;
+  __nsan_dump_shadow_mem((const char *)&a, sizeof(a), sizeof(a), 0);
+  __nsan_dump_shadow_mem((const char *)&b, sizeof(b), sizeof(b), 0);
+  SwapFT(&a, &b);
+  __nsan_dump_shadow_mem((const char *)&a, sizeof(a), sizeof(a), 0);
+  __nsan_dump_shadow_mem((const char *)&b, sizeof(b), sizeof(b), 0);
+  assert(a == 2.0 && b == 1.0);
+  SwapBitcasted(reinterpret_cast<uint64_t *>(&a),
+                reinterpret_cast<uint64_t *>(&b));
+  __nsan_dump_shadow_mem((const char *)&a, sizeof(a), sizeof(a), 0);
+  __nsan_dump_shadow_mem((const char *)&b, sizeof(b), sizeof(b), 0);
+  assert(a == 1.0 && b == 2.0);
+  // CHECK: 0x{{[a-f0-9]*}}:    d0 d1 d2 d3 d4 d5 d6 d7   (1.0{{.*}}
+  // CHECK-NEXT: 0x{{[a-f0-9]*}}:    d0 d1 d2 d3 d4 d5 d6 d7   (2.0{{.*}}
+  // CHECK-NEXT: 0x{{[a-f0-9]*}}:    d0 d1 d2 d3 d4 d5 d6 d7   (2.0{{.*}}
+  // CHECK-NEXT: 0x{{[a-f0-9]*}}:    d0 d1 d2 d3 d4 d5 d6 d7   (1.0{{.*}}
+  // CHECK-NEXT: 0x{{[a-f0-9]*}}:    d0 d1 d2 d3 d4 d5 d6 d7   (1.0{{.*}}
+  // CHECK-NEXT: 0x{{[a-f0-9]*}}:    d0 d1 d2 d3 d4 d5 d6 d7   (2.0{{.*}}
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/100906


More information about the llvm-commits mailing list