[ORC] Propagate out-of-band errors in callAsync.
authorLang Hames <lhames@gmail.com>
Mon, 11 Oct 2021 19:34:08 +0000 (12:34 -0700)
committerLang Hames <lhames@gmail.com>
Mon, 11 Oct 2021 21:23:50 +0000 (14:23 -0700)
Returned out-of-band errors should be wrapped as llvm::Errors and passed to the
SendDeserializedResult function. Failure to do this results in an assertion when
we try to deserialize from the WrapperFunctionResult while it's in the
out-of-band error state.

llvm/include/llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h
llvm/unittests/ExecutionEngine/Orc/WrapperFunctionUtilsTest.cpp

index 0dd581b..b1ca1f1 100644 (file)
@@ -492,6 +492,12 @@ public:
       RetT RetVal = detail::ResultDeserializer<SPSRetTagT, RetT>::makeValue();
       detail::ResultDeserializer<SPSRetTagT, RetT>::makeSafe(RetVal);
 
+      if (auto *ErrMsg = R.getOutOfBandError()) {
+        SDR(make_error<StringError>(ErrMsg, inconvertibleErrorCode()),
+            std::move(RetVal));
+        return;
+      }
+
       SPSInputBuffer IB(R.data(), R.size());
       if (auto Err = detail::ResultDeserializer<SPSRetTagT, RetT>::deserialize(
               RetVal, R.data(), R.size()))
index d672fcf..b94c123 100644 (file)
@@ -8,6 +8,7 @@
 
 #include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"
 #include "llvm/ADT/FunctionExtras.h"
+#include "llvm/Testing/Support/Error.h"
 #include "gtest/gtest.h"
 
 #include <future>
@@ -142,3 +143,19 @@ TEST(WrapperFunctionUtilsTest, WrapperFunctionCallAndHandleAsyncRet) {
       addAsyncWrapper, Result, 1, 2));
   EXPECT_EQ(Result, (int32_t)3);
 }
+
+static WrapperFunctionResult failingWrapper(const char *ArgData,
+                                            size_t ArgSize) {
+  return WrapperFunctionResult::createOutOfBandError("failed");
+}
+
+void asyncFailingWrapperCaller(unique_function<void(WrapperFunctionResult)> F,
+                               const char *ArgData, size_t ArgSize) {
+  F(failingWrapper(ArgData, ArgSize));
+}
+
+TEST(WrapperFunctionUtilsTest, WrapperFunctionCallFailingAsync) {
+  WrapperFunction<void()>::callAsync(asyncFailingWrapperCaller, [](Error Err) {
+    EXPECT_THAT_ERROR(std::move(Err), Failed());
+  });
+}