-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang][llvm][rtsan] Introduce RealtimeSanitizer clang codegen, llvm attributes #100120
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-compiler-rt-sanitizer @llvm/pr-subscribers-llvm-ir Author: Chris Apple (cjappl) ChangesThis is the second PR introducing the Realtime sanitizer. Review Contents
Please focus your reviewing on CodeGenFunciton, and the llvm attribute and how we attach it to a function given the FunctionEffects to be sure we have done this correctly. After this, users should be able to run rtsan end-to-end and get some usable functionality out of it. Reviewer support documentPlease see the reviewer support document for what our next steps are. If you want to see the previous review introducing the compiler-rt changes, it is here: #92460 Patch is 22.50 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/100120.diff 23 Files Affected:
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 4825979a974d2..8a4a29d589b9b 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -3527,6 +3527,11 @@ def NoSanitize : InheritableAttr {
bool hasCoverage() const {
return llvm::is_contained(sanitizers(), "coverage");
}
+
+ bool hasRealtime() const {
+ return llvm::is_contained(sanitizers(), "realtime");
+ }
+
}];
}
diff --git a/clang/include/clang/Basic/Sanitizers.def b/clang/include/clang/Basic/Sanitizers.def
index bee35e9dca7c3..8a5df643ffa0c 100644
--- a/clang/include/clang/Basic/Sanitizers.def
+++ b/clang/include/clang/Basic/Sanitizers.def
@@ -37,6 +37,9 @@
#endif
+// RealtimeSanitizer
+SANITIZER("realtime", Realtime)
+
// AddressSanitizer
SANITIZER("address", Address)
diff --git a/clang/include/clang/Driver/SanitizerArgs.h b/clang/include/clang/Driver/SanitizerArgs.h
index 47ef175302679..6c0df926aec5b 100644
--- a/clang/include/clang/Driver/SanitizerArgs.h
+++ b/clang/include/clang/Driver/SanitizerArgs.h
@@ -79,6 +79,7 @@ class SanitizerArgs {
bool needsStableAbi() const { return StableABI; }
bool needsMemProfRt() const { return NeedsMemProfRt; }
+ bool needsRtsanRt() const { return Sanitizers.has(SanitizerKind::Realtime); }
bool needsAsanRt() const { return Sanitizers.has(SanitizerKind::Address); }
bool needsHwasanRt() const {
return Sanitizers.has(SanitizerKind::HWAddress);
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index d582aba679ddc..7af7785515688 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -2408,6 +2408,12 @@ void CodeGenModule::ConstructAttributeList(StringRef Name,
FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
NBA = Fn->getAttr<NoBuiltinAttr>();
}
+
+ for (const FunctionEffectWithCondition &Fe : Fn->getFunctionEffects()) {
+ if (Fe.Effect.kind() == FunctionEffect::Kind::NonBlocking) {
+ FuncAttrs.addAttribute(llvm::Attribute::NonBlocking);
+ }
+ }
}
if (isa<FunctionDecl>(TargetDecl) || isa<VarDecl>(TargetDecl)) {
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 1e98bea8c8ce3..84ce2b20dd45d 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -31,6 +31,7 @@
#include "clang/AST/StmtObjC.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/CodeGenOptions.h"
+#include "clang/Basic/Sanitizers.h"
#include "clang/Basic/TargetBuiltins.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/CodeGen/CGFunctionInfo.h"
@@ -40,6 +41,9 @@
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/FPEnv.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/MDBuilder.h"
@@ -1410,6 +1414,35 @@ QualType CodeGenFunction::BuildFunctionArgList(GlobalDecl GD,
return ResTy;
}
+void InsertCallBeforeInstruction(llvm::Function *Fn,
+ llvm::Instruction &Instruction,
+ const char *FunctionName) {
+ llvm::LLVMContext &context = Fn->getContext();
+ llvm::FunctionType *FuncType =
+ llvm::FunctionType::get(llvm::Type::getVoidTy(context), false);
+ llvm::FunctionCallee Func =
+ Fn->getParent()->getOrInsertFunction(FunctionName, FuncType);
+ llvm::IRBuilder<> builder{&Instruction};
+ builder.CreateCall(Func, {});
+}
+
+void InsertCallAtFunctionEntryPoint(llvm::Function *Fn,
+ const char *InsertFnName) {
+
+ InsertCallBeforeInstruction(Fn, Fn->front().front(), InsertFnName);
+}
+
+void InsertCallAtAllFunctionExitPoints(llvm::Function *Fn,
+ const char *InsertFnName) {
+ for (auto &BB : *Fn) {
+ for (auto &I : BB) {
+ if (auto *RI = dyn_cast<llvm::ReturnInst>(&I)) {
+ InsertCallBeforeInstruction(Fn, I, InsertFnName);
+ }
+ }
+ }
+}
+
void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
const CGFunctionInfo &FnInfo) {
assert(Fn && "generating code for null Function");
@@ -1578,9 +1611,19 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
}
}
+ if (SanOpts.has(SanitizerKind::Realtime)) {
+ if (Fn->hasFnAttribute(llvm::Attribute::NonBlocking))
+ InsertCallAtFunctionEntryPoint(Fn, "__rtsan_realtime_enter");
+ }
+
// Emit the standard function epilogue.
FinishFunction(BodyRange.getEnd());
+ if (SanOpts.has(SanitizerKind::Realtime)) {
+ if (Fn->hasFnAttribute(llvm::Attribute::NonBlocking))
+ InsertCallAtAllFunctionExitPoints(Fn, "__rtsan_realtime_exit");
+ }
+
// If we haven't marked the function nothrow through other means, do
// a quick pass now to see if we can.
if (!CurFn->doesNotThrow())
diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp
index 1fd870b72286e..7b38f20fc8d05 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -552,11 +552,15 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
SanitizerKind::Leak | SanitizerKind::Thread |
SanitizerKind::Memory | SanitizerKind::KernelAddress |
SanitizerKind::Scudo | SanitizerKind::SafeStack),
- std::make_pair(SanitizerKind::MemTag,
- SanitizerKind::Address | SanitizerKind::KernelAddress |
- SanitizerKind::HWAddress |
- SanitizerKind::KernelHWAddress),
- std::make_pair(SanitizerKind::KCFI, SanitizerKind::Function)};
+ std::make_pair(SanitizerKind::MemTag, SanitizerKind::Address |
+ SanitizerKind::KernelAddress |
+ SanitizerKind::HWAddress |
+ SanitizerKind::KernelHWAddress),
+ std::make_pair(SanitizerKind::KCFI, SanitizerKind::Function),
+ std::make_pair(SanitizerKind::Realtime,
+ SanitizerKind::Address | SanitizerKind::Thread |
+ SanitizerKind::Undefined | SanitizerKind::Memory)};
+
// Enable toolchain specific default sanitizers if not explicitly disabled.
SanitizerMask Default = TC.getDefaultSanitizers() & ~AllRemove;
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 019df16a909f4..5c2040fdee8d7 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1430,6 +1430,8 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
if (!Args.hasArg(options::OPT_shared))
HelperStaticRuntimes.push_back("hwasan-preinit");
}
+ if (SanArgs.needsRtsanRt() && SanArgs.linkRuntimes())
+ SharedRuntimes.push_back("rtsan");
}
// The stats_client library is also statically linked into DSOs.
@@ -1455,6 +1457,11 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
StaticRuntimes.push_back("asan_cxx");
}
+ if (!SanArgs.needsSharedRt() && SanArgs.needsRtsanRt() &&
+ SanArgs.linkRuntimes()) {
+ StaticRuntimes.push_back("rtsan");
+ }
+
if (!SanArgs.needsSharedRt() && SanArgs.needsMemProfRt()) {
StaticRuntimes.push_back("memprof");
if (SanArgs.linkCXXRuntimes())
diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp
index c6f9d7beffb1d..28e735795cb2b 100644
--- a/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -1519,6 +1519,8 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
const char *sanitizer = nullptr;
if (Sanitize.needsUbsanRt()) {
sanitizer = "UndefinedBehaviorSanitizer";
+ } else if (Sanitize.needsRtsanRt()) {
+ sanitizer = "RealtimeSanitizer";
} else if (Sanitize.needsAsanRt()) {
sanitizer = "AddressSanitizer";
} else if (Sanitize.needsTsanRt()) {
@@ -1541,6 +1543,11 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
AddLinkSanitizerLibArgs(Args, CmdArgs, "asan");
}
}
+ if (Sanitize.needsRtsanRt()) {
+ assert(Sanitize.needsSharedRt() &&
+ "Static sanitizer runtimes not supported");
+ AddLinkSanitizerLibArgs(Args, CmdArgs, "rtsan");
+ }
if (Sanitize.needsLsanRt())
AddLinkSanitizerLibArgs(Args, CmdArgs, "lsan");
if (Sanitize.needsUbsanRt()) {
@@ -3477,6 +3484,7 @@ SanitizerMask Darwin::getSupportedSanitizers() const {
const bool IsAArch64 = getTriple().getArch() == llvm::Triple::aarch64;
SanitizerMask Res = ToolChain::getSupportedSanitizers();
Res |= SanitizerKind::Address;
+ Res |= SanitizerKind::Realtime;
Res |= SanitizerKind::PointerCompare;
Res |= SanitizerKind::PointerSubtract;
Res |= SanitizerKind::Leak;
diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp
index 2265138edbffb..aa8a219dc9745 100644
--- a/clang/lib/Driver/ToolChains/Linux.cpp
+++ b/clang/lib/Driver/ToolChains/Linux.cpp
@@ -798,6 +798,7 @@ SanitizerMask Linux::getSupportedSanitizers() const {
const bool IsHexagon = getTriple().getArch() == llvm::Triple::hexagon;
SanitizerMask Res = ToolChain::getSupportedSanitizers();
Res |= SanitizerKind::Address;
+ Res |= SanitizerKind::Realtime;
Res |= SanitizerKind::PointerCompare;
Res |= SanitizerKind::PointerSubtract;
Res |= SanitizerKind::Fuzzer;
diff --git a/clang/test/Driver/fsanitize.c b/clang/test/Driver/fsanitize.c
index db14f6e195c64..c3ce8b5ae8b72 100644
--- a/clang/test/Driver/fsanitize.c
+++ b/clang/test/Driver/fsanitize.c
@@ -1038,3 +1038,51 @@
// RUN: not %clang --target=aarch64-none-elf -fsanitize=dataflow %s -### 2>&1 | FileCheck %s -check-prefix=UNSUPPORTED-BAREMETAL
// RUN: not %clang --target=arm-arm-none-eabi -fsanitize=shadow-call-stack %s -### 2>&1 | FileCheck %s -check-prefix=UNSUPPORTED-BAREMETAL
// UNSUPPORTED-BAREMETAL: unsupported option '-fsanitize={{.*}}' for target
+
+// RUN: %clang --target=x86_64-apple-darwin -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-DARWIN
+// CHECK-RTSAN-X86-64-DARWIN-NOT: unsupported option
+
+// RUN: %clang --target=x86_64-apple-darwin -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-DARWIN
+// CHECK-RTSAN-X86-64-DARWIN-NOT: unsupported option
+// RUN: %clang --target=x86_64-apple-macos -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-MACOS
+// CHECK-RTSAN-X86-64-MACOS-NOT: unsupported option
+// RUN: %clang --target=arm64-apple-macos -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-ARM64-MACOS
+// CHECK-RTSAN-ARM64-MACOS-NOT: unsupported option
+
+// RUN: %clang --target=arm64-apple-ios-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-ARM64-IOSSIMULATOR
+// CHECK-RTSAN-ARM64-IOSSIMULATOR-NOT: unsupported option
+
+// RUN: %clang --target=arm64-apple-watchos-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-ARM64-WATCHOSSIMULATOR
+// CHECK-RTSAN-ARM64-WATCHOSSIMULATOR-NOT: unsupported option
+
+// RUN: %clang --target=arm64-apple-tvos-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-ARM64-TVOSSIMULATOR
+// CHECK-RTSAN-ARM64-TVOSSIMULATOR-NOT: unsupported option
+
+// RUN: %clang --target=x86_64-apple-ios-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-IOSSIMULATOR
+// CHECK-RTSAN-X86-64-IOSSIMULATOR-NOT: unsupported option
+
+// RUN: %clang --target=x86_64-apple-watchos-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-WATCHOSSIMULATOR
+// CHECK-RTSAN-X86-64-WATCHOSSIMULATOR-NOT: unsupported option
+
+// RUN: %clang --target=x86_64-apple-tvos-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-TVOSSIMULATOR
+// CHECK-RTSAN-X86-64-TVOSSIMULATOR-NOT: unsupported option
+
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-LINUX
+// CHECK-RTSAN-X86-64-LINUX-NOT: unsupported option
+
+// RUN: not %clang --target=i386-pc-openbsd -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-OPENBSD
+// CHECK-RTSAN-OPENBSD: unsupported option '-fsanitize=realtime' for target 'i386-pc-openbsd'
+
+// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=realtime,thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-REALTIME-TSAN
+// CHECK-REALTIME-TSAN: error: invalid argument '-fsanitize=realtime' not allowed with '-fsanitize=thread'
+
+// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=realtime,address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-REALTIME-ASAN
+// CHECK-REALTIME-ASAN: error: invalid argument '-fsanitize=realtime' not allowed with '-fsanitize=address'
+
+// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=realtime,memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-REALTIME-MSAN
+// CHECK-REALTIME-MSAN: error: invalid argument '-fsanitize=realtime' not allowed with '-fsanitize=memory'
+
+// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=realtime,undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-REALTIME-UBSAN
+// CHECK-REALTIME-UBSAN: error: invalid argument '-fsanitize=realtime' not allowed with '-fsanitize=undefined'
+
+
diff --git a/clang/test/Driver/rtsan.c b/clang/test/Driver/rtsan.c
new file mode 100644
index 0000000000000..1ccf52d34873d
--- /dev/null
+++ b/clang/test/Driver/rtsan.c
@@ -0,0 +1,12 @@
+// RUN: %clang -target x86_64-unknown-linux -fsanitize=realtime %s -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang -O1 -target x86_64-unknown-linux -fsanitize=realtime %s -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang -O2 -target x86_64-unknown-linux -fsanitize=realtime %s -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang -O3 -target x86_64-unknown-linux -fsanitize=realtime %s -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang -target x86_64-unknown-linux -fsanitize=realtime %s -S -emit-llvm -flto=thin -o - | FileCheck %s
+// RUN: %clang -O2 -target x86_64-unknown-linux -fsanitize=realtime %s -S -emit-llvm -flto=thin -o - | FileCheck %s
+// RUN: %clang -target x86_64-unknown-linux -fsanitize=realtime %s -S -emit-llvm -flto -o - | FileCheck %s
+// RUN: %clang -O2 -target x86_64-unknown-linux -fsanitize=realtime %s -S -emit-llvm -flto -o - | FileCheck %s
+
+int foo(int *a) [[clang::nonblocking]] { return *a; }
+// CHECK: __rtsan_realtime_enter
+// CHECK: __rtsan_realtime_exit
diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors.cpp
index 4d5423ec629d2..833062c3de41e 100644
--- a/compiler-rt/lib/rtsan/rtsan_interceptors.cpp
+++ b/compiler-rt/lib/rtsan/rtsan_interceptors.cpp
@@ -39,7 +39,6 @@
using namespace __sanitizer;
-using __rtsan::rtsan_init_is_running;
using __rtsan::rtsan_initialized;
namespace {
@@ -49,6 +48,9 @@ struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> {
} // namespace
void ExpectNotRealtime(const char *intercepted_function_name) {
+ if (!rtsan_initialized)
+ __rtsan_init();
+
__rtsan::GetContextForThisThread().ExpectNotRealtime(
intercepted_function_name);
}
diff --git a/compiler-rt/lib/rtsan/tests/CMakeLists.txt b/compiler-rt/lib/rtsan/tests/CMakeLists.txt
index 3b783c90c2658..0320bbad59218 100644
--- a/compiler-rt/lib/rtsan/tests/CMakeLists.txt
+++ b/compiler-rt/lib/rtsan/tests/CMakeLists.txt
@@ -60,14 +60,13 @@ endif()
foreach(arch ${RTSAN_TEST_ARCH})
set(RtsanTestObjects)
- # TODO: Re-enable once -fsanitize=realtime exists in clang driver
- #generate_compiler_rt_tests(RtsanTestObjects
- # RtsanUnitTests "Rtsan-${arch}-Test" ${arch}
- # COMPILE_DEPS ${RTSAN_UNITTEST_HEADERS}
- # SOURCES ${RTSAN_INST_TEST_SOURCES} ${COMPILER_RT_GOOGLETEST_SOURCES}
- # DEPS rtsan
- # CFLAGS ${RTSAN_UNITTEST_CFLAGS} -fsanitize=realtime
- # LINK_FLAGS ${RTSAN_UNITTEST_LINK_FLAGS} -fsanitize=realtime)
+ generate_compiler_rt_tests(RtsanTestObjects
+ RtsanUnitTests "Rtsan-${arch}-Test" ${arch}
+ COMPILE_DEPS ${RTSAN_UNITTEST_HEADERS}
+ SOURCES ${RTSAN_INST_TEST_SOURCES} ${COMPILER_RT_GOOGLETEST_SOURCES}
+ DEPS rtsan
+ CFLAGS ${RTSAN_UNITTEST_CFLAGS} -fsanitize=realtime
+ LINK_FLAGS ${RTSAN_UNITTEST_LINK_FLAGS} -fsanitize=realtime)
set(RTSAN_TEST_RUNTIME RTRtsanTest.${arch})
if(APPLE)
diff --git a/compiler-rt/test/rtsan/CMakeLists.txt b/compiler-rt/test/rtsan/CMakeLists.txt
index e1f9eb39408dc..59fc5a29703fe 100644
--- a/compiler-rt/test/rtsan/CMakeLists.txt
+++ b/compiler-rt/test/rtsan/CMakeLists.txt
@@ -1,14 +1,3 @@
-
-
-
-
-######
-# TODO: Full lit tests coming in a future review when we introduce the codegen
-######
-
-
-
-
set(RTSAN_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(RTSAN_TESTSUITES)
diff --git a/compiler-rt/test/rtsan/test_rtsan.cpp b/compiler-rt/test/rtsan/test_rtsan.cpp
new file mode 100644
index 0000000000000..101aadc56e960
--- /dev/null
+++ b/compiler-rt/test/rtsan/test_rtsan.cpp
@@ -0,0 +1,17 @@
+// RUN: %clangxx -fsanitize=realtime %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s
+// UNSUPPORTED: ios
+
+// Intent: Ensure that an intercepted call in a [[clang::nonblocking]] function
+// is flagged as an error. Basic smoke test.
+
+#include <stdlib.h>
+
+void violation() [[clang::nonblocking]] { void *Ptr = malloc(2); }
+
+int main() {
+ violation();
+ return 0;
+ // CHECK: {{.*Real-time violation.*}}
+ // CHECK: {{.*malloc*}}
+}
diff --git a/compiler-rt/test/rtsan/test_rtsan_inactive.cpp b/compiler-rt/test/rtsan/test_rtsan_inactive.cpp
new file mode 100644
index 0000000000000..86907df6dfa16
--- /dev/null
+++ b/compiler-rt/test/rtsan/test_rtsan_inactive.cpp
@@ -0,0 +1,23 @@
+// RUN: %clangxx %s -o %t
+// RUN: %run %t 2>&1 | FileCheck %s
+// UNSUPPORTED: ios
+
+// Intent: Ensure [[clang::nonblocking]] has no impact if -fsanitize=realtime is not used
+
+#include <stdio.h>
+#include <stdlib.h>
+
+// In this test, we don't use the -fsanitize=realtime flag, so nothing
+// should happen here
+void violation() [[clang::nonblocking]] { void *Ptr = malloc(2); }
+
+int main() {
+ printf("Starting run\n");
+ violation();
+ printf("No violations ended the program\n");
+ return 0;
+ // CHECK: {{.*Starting run.*}}
+ // CHECK NOT: {{.*Real-time violation.*}}
+ // CHECK NOT: {{.*malloc*}}
+ // CHECK: {{.*No violations ended the program.*}}
+}
diff --git a/compiler-rt/test/sanitizer_common/CMakeLists.txt b/compiler-rt/test/sanitizer_common/CMakeLists.txt
index fa06b82acebd9..90bb55db3d1a6 100644
--- a/compiler-rt/test/sanitizer_common/CMakeLists.txt
+++ b/compiler-rt/test/sanitizer_common/CMakeLists.txt
@@ -7,7 +7,7 @@ set(SANITIZER_COMMON_TESTSUITES)
# FIXME(dliew): We should switch to COMPILER_RT_SANITIZERS_TO_BUILD instead of
# the hard coded `SUPPORTED_TOOLS_INIT` list once we know that the other
# sanitizers work.
-set(SUPPORTED_TOOLS_INIT asan lsan hwasan msan tsan ubsan)
+set(SUPPORTED_TOOLS_INIT asan lsan hwasan msan rtsan tsan ubsan)
set(SUPPORTED_TOOLS)
foreach(SANITIZER_TOOL ${SUPPORTED_TOOLS_INIT})
string(TOUPPER ${SANITIZER_TOOL} SANITIZER_TOOL_UPPER)
diff --git a/compiler-rt/test/sanitizer_common/lit.common.cfg.py b/compiler-rt/test/sanitizer_common/lit.common.cfg.py
index 04af4816eb6e7..5406e8838f2fc 100644
--- a/compiler-rt/test/sanitizer_common/lit.common.cfg.py
+++ b/compiler-rt/test/sanitizer_common/lit.common.cfg.py
@@ -18,6 +18,9 @@
tool_options = "HWASAN_OPTIONS"
if not config.has_lld:
config.unsupported = True
+elif config.tool_name == "rtsan":
+ tool_cflags = ["-fsanitize=realtime"]
+ tool_options = "RTSAN_OPTIONS"
elif config.tool_name == "tsan":
tool_cflags = ["-fsanitize=thread"]
tool_options = "TSAN_OPTIONS"
diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
index fb88f2fe75adb..61b046c26a97f 100644
--- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
@@ -758,6 +758,7 @@ enum AttributeKindCodes {...
[truncated]
|
CC For review: @AaronBallman @Sirraide @vitalybuka @MaskRay @dougsonos - would you make sure the work with the attribute and function effects make sense? And co-author: @davidtrevelyan |
Can we split into 3 patches?
And each patch should have tests |
Thanks for the suggestion @vitalybuka - after some thought, we think we can remove the llvm changes entirely now, and so here's our plan:
Hope that all makes sense - please let us know if any alarm bells are ringing in your head. We will of course also sweep our patch for any missing test coverage. Thanks again! |
Closing in favor of these two reviews to begin with, a 3rd will be added with the lit test components after these are merged:
|
This is the second PR introducing the Realtime sanitizer.
Review Contents
__rtsan_realtime_enter/exit
callsPlease focus your reviewing on CodeGenFunciton, and the llvm attribute and how we attach it to a function given the FunctionEffects to be sure we have done this correctly.
After this, users should be able to run rtsan end-to-end and get some usable functionality out of it.
Reviewer support document
Please see the reviewer support document for what our next steps are. If you want to see the previous review introducing the compiler-rt changes, it is here: #92460. Original LLVM discourse thread talking about this as well as the FunctionEffects proposal is here (https://discourse.llvm.org/t/rfc-nolock-and-noalloc-attributes/76837)