From 36ac5592633ff8de29611db28a6ffe38fc3d5502 Mon Sep 17 00:00:00 2001 From: David Trevelyan Date: Tue, 25 Nov 2025 22:23:10 +0000 Subject: [PATCH] [rtsan] Handle attributed IR function declarations Addresses https://github.com/llvm/llvm-project/issues/169377. Previously, the RealtimeSanitizer pass only handled attributed function definitions in IR, and attributed function declarations caused it to crash. To fix the issue, we must check whether the IR function is empty before attempting to do any manipulation of its instructions. --- .../Instrumentation/RealtimeSanitizer.cpp | 16 +++++++--------- .../RealtimeSanitizer/rtsan_attrib_declare.ll | 12 ++++++++++++ 2 files changed, 19 insertions(+), 9 deletions(-) create mode 100644 llvm/test/Instrumentation/RealtimeSanitizer/rtsan_attrib_declare.ll diff --git a/llvm/lib/Transforms/Instrumentation/RealtimeSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/RealtimeSanitizer.cpp index 5ef6ffb58a7c1..adb0e518c6074 100644 --- a/llvm/lib/Transforms/Instrumentation/RealtimeSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/RealtimeSanitizer.cpp @@ -61,23 +61,21 @@ static void insertCallAtAllFunctionExitPoints(Function &Fn, insertCallBeforeInstruction(Fn, I, InsertFnName, FunctionArgs); } -static PreservedAnalyses rtsanPreservedCFGAnalyses() { - PreservedAnalyses PA; - PA.preserveSet(); - return PA; -} +static void runSanitizeRealtime(Function &Fn) { + if (Fn.empty()) + return; -static PreservedAnalyses runSanitizeRealtime(Function &Fn) { insertCallAtFunctionEntryPoint(Fn, "__rtsan_realtime_enter", {}); insertCallAtAllFunctionExitPoints(Fn, "__rtsan_realtime_exit", {}); - return rtsanPreservedCFGAnalyses(); } -static PreservedAnalyses runSanitizeRealtimeBlocking(Function &Fn) { +static void runSanitizeRealtimeBlocking(Function &Fn) { + if (Fn.empty()) + return; + IRBuilder<> Builder(&Fn.front().front()); Value *Name = Builder.CreateGlobalString(demangle(Fn.getName())); insertCallAtFunctionEntryPoint(Fn, "__rtsan_notify_blocking_call", {Name}); - return rtsanPreservedCFGAnalyses(); } PreservedAnalyses RealtimeSanitizerPass::run(Module &M, diff --git a/llvm/test/Instrumentation/RealtimeSanitizer/rtsan_attrib_declare.ll b/llvm/test/Instrumentation/RealtimeSanitizer/rtsan_attrib_declare.ll new file mode 100644 index 0000000000000..a5336b9e9e491 --- /dev/null +++ b/llvm/test/Instrumentation/RealtimeSanitizer/rtsan_attrib_declare.ll @@ -0,0 +1,12 @@ +; RUN: opt < %s -passes='rtsan' -S | FileCheck %s + +declare void @declared_realtime_function() sanitize_realtime #0 + +declare void @declared_blocking_function() sanitize_realtime_blocking #0 + +; RealtimeSanitizer pass should ignore attributed functions that are just declarations +; CHECK: declared_realtime_function +; CHECK-EMPTY: +; CHECK: declared_blocking_function +; CHECK-EMPTY: +