From 0e43f3b04d527776458df7aa1d7ce1787ff0b32f Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Sun, 18 Sep 2022 17:47:12 -0700 Subject: [PATCH] [ORC][ORC-RT] Make WrapperFunctionCall::Create support void functions. Serialized calls to void-wrapper-functions should have zero bytes of argument data, but accessing ArgData[0] may (and will, in the case of SmallVector) fail if the argument data buffer is empty. This commit fixes the issue by adding a check for empty argument buffers. --- .../lib/orc/tests/unit/wrapper_function_utils_test.cpp | 4 ++++ compiler-rt/lib/orc/wrapper_function_utils.h | 3 ++- .../llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h | 3 ++- .../ExecutionEngine/Orc/WrapperFunctionUtilsTest.cpp | 5 +++++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/compiler-rt/lib/orc/tests/unit/wrapper_function_utils_test.cpp b/compiler-rt/lib/orc/tests/unit/wrapper_function_utils_test.cpp index 031238307b4f..8d4b9b3cba2b 100644 --- a/compiler-rt/lib/orc/tests/unit/wrapper_function_utils_test.cpp +++ b/compiler-rt/lib/orc/tests/unit/wrapper_function_utils_test.cpp @@ -66,6 +66,10 @@ TEST(WrapperFunctionUtilsTest, WrapperFunctionResultFromOutOfBandError) { EXPECT_TRUE(strcmp(R.getOutOfBandError(), TestString) == 0); } +TEST(WrapperFunctionUtilsTest, WrapperFunctionCCallCreateEmpty) { + EXPECT_TRUE(!!WrapperFunctionCall::Create>(ExecutorAddr())); +} + static void voidNoop() {} static __orc_rt_CWrapperFunctionResult voidNoopWrapper(const char *ArgData, diff --git a/compiler-rt/lib/orc/wrapper_function_utils.h b/compiler-rt/lib/orc/wrapper_function_utils.h index 17aa8bb671fd..b48891b3b750 100644 --- a/compiler-rt/lib/orc/wrapper_function_utils.h +++ b/compiler-rt/lib/orc/wrapper_function_utils.h @@ -408,7 +408,8 @@ public: const ArgTs &...Args) { ArgDataBufferType ArgData; ArgData.resize(SPSSerializer::size(Args...)); - SPSOutputBuffer OB(&ArgData[0], ArgData.size()); + SPSOutputBuffer OB(ArgData.empty() ? nullptr : ArgData.data(), + ArgData.size()); if (SPSSerializer::serialize(OB, Args...)) return WrapperFunctionCall(FnAddr, std::move(ArgData)); return make_error("Cannot serialize arguments for " diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h b/llvm/include/llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h index eb3fb084b28b..bdb5ac143c34 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h @@ -636,7 +636,8 @@ public: const ArgTs &...Args) { ArgDataBufferType ArgData; ArgData.resize(SPSSerializer::size(Args...)); - SPSOutputBuffer OB(&ArgData[0], ArgData.size()); + SPSOutputBuffer OB(ArgData.empty() ? nullptr : ArgData.data(), + ArgData.size()); if (SPSSerializer::serialize(OB, Args...)) return WrapperFunctionCall(FnAddr, std::move(ArgData)); return make_error("Cannot serialize arguments for " diff --git a/llvm/unittests/ExecutionEngine/Orc/WrapperFunctionUtilsTest.cpp b/llvm/unittests/ExecutionEngine/Orc/WrapperFunctionUtilsTest.cpp index b94c123ae22b..1ed690ae9b98 100644 --- a/llvm/unittests/ExecutionEngine/Orc/WrapperFunctionUtilsTest.cpp +++ b/llvm/unittests/ExecutionEngine/Orc/WrapperFunctionUtilsTest.cpp @@ -58,6 +58,11 @@ TEST(WrapperFunctionUtilsTest, WrapperFunctionResultFromOutOfBandError) { EXPECT_TRUE(strcmp(R.getOutOfBandError(), TestString) == 0); } +TEST(WrapperFunctionUtilsTest, WrapperFunctionCCallCreateEmpty) { + EXPECT_THAT_EXPECTED( + WrapperFunctionCall::Create>(ExecutorAddr()), Succeeded()); +} + static void voidNoop() {} class AddClass {