[llvm] [orc-rt] Make Session::reportError(Error) noexcept. (PR #225651)

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 23 02:13:34 PDT 2026


https://github.com/lhames created https://github.com/llvm/llvm-project/pull/225651

Session::reportError is called in contexts where throwing would be unsafe (e.g. while holding another Error value to return via the stack), so it must not throw.

>From 9c396ffeb642bd1baa0b5488b4f434d49b8b6246 Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at gmail.com>
Date: Wed, 23 Sep 2026 18:46:22 +1000
Subject: [PATCH] [orc-rt] Make Session::reportError(Error) noexcept.

Session::reportError is called in contexts where throwing would be
unsafe (e.g. while holding another Error value to return via the stack),
so it must not throw.
---
 orc-rt/include/orc-rt/bedrock/Session.h       |  6 +++---
 orc-rt/test/unit/CommonTestUtils.h            |  6 ++++--
 .../bedrock/InProcessControllerAccessTest.cpp | 10 +++++-----
 orc-rt/test/unit/bedrock/SessionTest.cpp      | 20 ++++++++-----------
 .../bedrock/SimpleNativeMemoryMapTest.cpp     | 12 +++++------
 5 files changed, 25 insertions(+), 29 deletions(-)

diff --git a/orc-rt/include/orc-rt/bedrock/Session.h b/orc-rt/include/orc-rt/bedrock/Session.h
index 7cdb45f59a000f..66128643d3f0ca 100644
--- a/orc-rt/include/orc-rt/bedrock/Session.h
+++ b/orc-rt/include/orc-rt/bedrock/Session.h
@@ -71,7 +71,7 @@ class Session {
   };
 
 public:
-  using ErrorReporterFn = move_only_function<void(Error)>;
+  using ErrorReporterFn = move_only_function<void(Error) noexcept>;
   using OnDisconnectFn = move_only_function<void(Error)>;
   using OnDetachFn = move_only_function<void()>;
   using OnShutdownFn = move_only_function<void()>;
@@ -190,7 +190,7 @@ class Session {
     virtual void disconnect() = 0;
 
     /// Report an error to the session.
-    void reportError(Error Err) { S.reportError(std::move(Err)); }
+    void reportError(Error Err) noexcept { S.reportError(std::move(Err)); }
 
     /// Call the handler in the controller associated with the given tag.
     ///
@@ -339,7 +339,7 @@ class Session {
   const ExecutorProcessInfo &processInfo() const noexcept { return EPI; }
 
   /// Report an error via the ErrorReporter function.
-  void reportError(Error Err) { ReportError(std::move(Err)); }
+  void reportError(Error Err) noexcept { ReportError(std::move(Err)); }
 
   /// Set a handler to be called when the Session's controller connection ends.
   ///
diff --git a/orc-rt/test/unit/CommonTestUtils.h b/orc-rt/test/unit/CommonTestUtils.h
index 65fa6a1f0e4071..9f94db5ddac408 100644
--- a/orc-rt/test/unit/CommonTestUtils.h
+++ b/orc-rt/test/unit/CommonTestUtils.h
@@ -29,7 +29,9 @@
 
 #include "gtest/gtest.h"
 
-inline void noErrors(orc_rt::Error Err) { orc_rt::cantFail(std::move(Err)); }
+inline void noErrors(orc_rt::Error Err) noexcept {
+  orc_rt::cantFail(std::move(Err));
+}
 
 /// ReportError callback for tests that records the message of every reported
 /// error, in the order reported.
@@ -37,7 +39,7 @@ class AccumulateErrors {
 public:
   AccumulateErrors(std::vector<std::string> &ErrMsgs) : ErrMsgs(ErrMsgs) {}
 
-  void operator()(orc_rt::Error Err) {
+  void operator()(orc_rt::Error Err) noexcept {
     ErrMsgs.push_back(orc_rt::toString(std::move(Err)));
   }
 
diff --git a/orc-rt/test/unit/bedrock/InProcessControllerAccessTest.cpp b/orc-rt/test/unit/bedrock/InProcessControllerAccessTest.cpp
index 29fd2c537fd7a1..f936105210b118 100644
--- a/orc-rt/test/unit/bedrock/InProcessControllerAccessTest.cpp
+++ b/orc-rt/test/unit/bedrock/InProcessControllerAccessTest.cpp
@@ -17,12 +17,14 @@
 
 #include "BedrockTestUtils.h"
 #include "CommonTestUtils.h"
+#include "ErrorMatchers.h"
 
 #include <deque>
 #include <optional>
 #include <string>
 
 using namespace orc_rt;
+using namespace orc_rt::test;
 
 namespace {
 
@@ -173,7 +175,7 @@ TEST(InProcessControllerAccessTest, OnConnectFailureIsReportedAndDetaches) {
   cantFail(std::move(Reported)); // force checked state
 
   Session S(mockExecutorProcessInfo(), noDispatch,
-            [&](Error E) { Reported = std::move(E); });
+            [&](Error E) noexcept { Reported = std::move(E); });
 
   S.attach<InProcessControllerAccess>(
       BootstrapInfo(S),
@@ -183,10 +185,8 @@ TEST(InProcessControllerAccessTest, OnConnectFailureIsReportedAndDetaches) {
         return make_error<StringError>("fake connect failure");
       });
 
-  if (Reported)
-    EXPECT_EQ(toString(std::move(Reported)), "fake connect failure");
-  else
-    ADD_FAILURE() << "Expected OnConnect error to be reported";
+  EXPECT_THAT_ERROR(std::move(Reported),
+                    FailedWithMessage("fake connect failure"));
 
   // A subsequent call to the controller should now fail with "no controller
   // attached" (i.e. the Session detached on the OnConnect error).
diff --git a/orc-rt/test/unit/bedrock/SessionTest.cpp b/orc-rt/test/unit/bedrock/SessionTest.cpp
index 967075da542d42..41fc8738696e0a 100644
--- a/orc-rt/test/unit/bedrock/SessionTest.cpp
+++ b/orc-rt/test/unit/bedrock/SessionTest.cpp
@@ -21,6 +21,7 @@
 
 #include "BedrockTestUtils.h"
 #include "CommonTestUtils.h"
+#include "ErrorMatchers.h"
 
 #include <chrono>
 #include <deque>
@@ -28,6 +29,7 @@
 #include <optional>
 
 using namespace orc_rt;
+using namespace orc_rt::test;
 using ::testing::Eq;
 using ::testing::Optional;
 
@@ -338,13 +340,10 @@ TEST(SessionTest, ReportError) {
   cantFail(std::move(E)); // Force error into checked state.
 
   Session S(mockExecutorProcessInfo(), noDispatch,
-            [&](Error Err) { E = std::move(Err); });
+            [&](Error Err) noexcept { E = std::move(Err); });
   S.reportError(make_error<StringError>("foo"));
 
-  if (E)
-    EXPECT_EQ(toString(std::move(E)), "foo");
-  else
-    ADD_FAILURE() << "Missing error value";
+  EXPECT_THAT_ERROR(std::move(E), FailedWithMessage("foo"));
 }
 
 TEST(SessionTest, ReportErrorsViaSession) {
@@ -353,13 +352,10 @@ TEST(SessionTest, ReportErrorsViaSession) {
 
   // Check that the ReportErrorsViaSession utility works as advertised.
   Session S(mockExecutorProcessInfo(), noDispatch,
-            [&](Error Err) { E = std::move(Err); });
+            [&](Error Err) noexcept { E = std::move(Err); });
   (ReportErrorsViaSession(S))(make_error<StringError>("foo"));
 
-  if (E)
-    EXPECT_EQ(toString(std::move(E)), "foo");
-  else
-    ADD_FAILURE() << "Missing error value";
+  EXPECT_THAT_ERROR(std::move(E), FailedWithMessage("foo"));
 }
 
 TEST(SessionTest, SingleService) {
@@ -858,9 +854,9 @@ TEST(ControllerAccessTest, FailConnect) {
   // Simulate failure to connect.
   bool GotError = false;
   std::string ErrMsg = "failed to connect";
-  Session S(mockExecutorProcessInfo(), noDispatch, [&](Error Err) {
+  Session S(mockExecutorProcessInfo(), noDispatch, [&](Error Err) noexcept {
     GotError = true;
-    EXPECT_EQ(toString(std::move(Err)), ErrMsg);
+    EXPECT_THAT_ERROR(std::move(Err), FailedWithMessage(ErrMsg));
   });
   BootstrapInfo BI(S);
   S.attach<MockControllerAccess>(
diff --git a/orc-rt/test/unit/bedrock/SimpleNativeMemoryMapTest.cpp b/orc-rt/test/unit/bedrock/SimpleNativeMemoryMapTest.cpp
index 23d3cd7393d2bf..978b8ad4da2ed0 100644
--- a/orc-rt/test/unit/bedrock/SimpleNativeMemoryMapTest.cpp
+++ b/orc-rt/test/unit/bedrock/SimpleNativeMemoryMapTest.cpp
@@ -17,6 +17,7 @@
 #include "AllocActionTestUtils.h"
 #include "BedrockTestUtils.h"
 #include "CommonTestUtils.h"
+#include "ErrorMatchers.h"
 #include "gtest/gtest.h"
 
 #include <cstring>
@@ -24,6 +25,7 @@
 #include <vector>
 
 using namespace orc_rt;
+using namespace orc_rt::test;
 
 // Write the given value to the address pointed to by P.
 static orc_rt_WrapperFunctionBuffer
@@ -188,8 +190,7 @@ TEST(SimpleNativeMemoryMapTest, ReleaseMultipleReportsErrors) {
   // Test that releaseMultiple reports errors via Session::reportError
   // when some addresses aren't recognized.
   std::vector<std::string> Errors;
-  Session S(mockExecutorProcessInfo(), noDispatch,
-            [&](Error Err) { Errors.push_back(toString(std::move(Err))); });
+  Session S(mockExecutorProcessInfo(), noDispatch, AccumulateErrors(Errors));
   SimpleSymbolTable ThrowAway;
   auto SNMM = cantFail(SimpleNativeMemoryMap::Create(S, ThrowAway));
 
@@ -210,8 +211,7 @@ TEST(SimpleNativeMemoryMapTest, DeinitializeMultipleReportsErrors) {
   // Test that deinitializeMultiple reports errors via Session::reportError
   // when some addresses aren't recognized.
   std::vector<std::string> Errors;
-  Session S(mockExecutorProcessInfo(), noDispatch,
-            [&](Error Err) { Errors.push_back(toString(std::move(Err))); });
+  Session S(mockExecutorProcessInfo(), noDispatch, AccumulateErrors(Errors));
   SimpleSymbolTable ThrowAway;
   auto SNMM = cantFail(SimpleNativeMemoryMap::Create(S, ThrowAway));
 
@@ -224,9 +224,7 @@ TEST(SimpleNativeMemoryMapTest, DeinitializeMultipleReportsErrors) {
   // This should fail and report the error.
   std::future<Error> DeinitResult;
   SNMM->deinitializeMultiple(waitFor(DeinitResult), {Addr});
-  auto Err = DeinitResult.get();
-  EXPECT_TRUE(!!Err);
-  consumeError(std::move(Err));
+  EXPECT_THAT_ERROR(DeinitResult.get(), Failed());
 
   EXPECT_EQ(Errors.size(), 1U);
 



More information about the llvm-commits mailing list