// RUN: %clangxx -fsanitize=realtime %s -o %t // RUN: %env_rtsan_opts=halt_on_error=false %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NOSUPPRESSIONS // RUN: %env_rtsan_opts=suppressions='%s.supp':print_stats_on_exit=true not %run %t 2>&1 | FileCheck %s // UNSUPPORTED: ios // Intent: Ensure that suppressions work as intended #include #include #include #include #include std::atomic cas_atomic{0}; void *MallocViolation() { return malloc(10); } void VectorViolations() { // All of these should be suppressed by *vector* std::vector v(10); v.resize(20); v.clear(); v.resize(0); v.push_back(1); v.reserve(10); } void BlockFunc() [[clang::blocking]] { int expected = 0; while (!cas_atomic.compare_exchange_weak(expected, 1)) { expected = cas_atomic.load(); } } void *process() [[clang::nonblocking]] { void *ptr = MallocViolation(); // Suppressed call-stack-contains VectorViolations(); // Suppressed call-stack-contains with regex BlockFunc(); // Suppressed function-name-matches free(ptr); // Suppressed function-name-matches // This is the one that should abort the program // Everything else is suppressed usleep(1); return ptr; } int main() { process(); return 0; } // CHECK-NOT: failed to open suppressions file // CHECK: Intercepted call to real-time unsafe function // CHECK-SAME: usleep // CHECK-NOT: Intercepted call to real-time unsafe function // CHECK-NOT: malloc // CHECK-NOT: vector // CHECK-NOT: free // CHECK-NOT: BlockFunc // CHECK: RealtimeSanitizer exit stats: // CHECK: Suppression count: 7 // CHECK-NOSUPPRESSIONS: malloc // CHECK-NOSUPPRESSIONS: vector // CHECK-NOSUPPRESSIONS: free // CHECK-NOSUPPRESSIONS: BlockFunc // CHECK-NOSUPPRESSIONS: usleep