]> granicus.if.org Git - llvm/commitdiff
[Error] Add an optional error message to cantFail.
authorLang Hames <lhames@gmail.com>
Tue, 29 Aug 2017 23:29:09 +0000 (23:29 +0000)
committerLang Hames <lhames@gmail.com>
Tue, 29 Aug 2017 23:29:09 +0000 (23:29 +0000)
cantFail is the moral equivalent of an assertion that the wrapped call must
return a success value. This patch allows clients to include an associated
error message (the same way they would for an assertion for llvm_unreachable).

If the error message is not specified it will default to: "Failure value
returned from cantFail wrapped call".

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@312066 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Support/Error.h
unittests/Support/ErrorTest.cpp

index 6aca32bf076dcb00c5b3d8574b0f2c57c65a27eb..bb40dbee053f044686c495c0438c265c2c5fb20f 100644 (file)
@@ -676,9 +676,12 @@ LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err,
 ///
 ///   cantFail(foo(false));
 ///   @endcode
-inline void cantFail(Error Err) {
-  if (Err)
-    llvm_unreachable("Failure value returned from cantFail wrapped call");
+inline void cantFail(Error Err, const char *Msg = nullptr) {
+  if (Err) {
+    if (!Msg)
+      Msg = "Failure value returned from cantFail wrapped call";
+    llvm_unreachable(Msg);
+  }
 }
 
 /// Report a fatal error if ValOrErr is a failure value, otherwise unwraps and
@@ -695,11 +698,14 @@ inline void cantFail(Error Err) {
 ///   int X = cantFail(foo(false));
 ///   @endcode
 template <typename T>
-T cantFail(Expected<T> ValOrErr) {
+T cantFail(Expected<T> ValOrErr, const char *Msg = nullptr) {
   if (ValOrErr)
     return std::move(*ValOrErr);
-  else
-    llvm_unreachable("Failure value returned from cantFail wrapped call");
+  else {
+    if (!Msg)
+      Msg = "Failure value returned from cantFail wrapped call";
+    llvm_unreachable(Msg);
+  }
 }
 
 /// Report a fatal error if ValOrErr is a failure value, otherwise unwraps and
@@ -716,11 +722,14 @@ T cantFail(Expected<T> ValOrErr) {
 ///   Bar &X = cantFail(foo(false));
 ///   @endcode
 template <typename T>
-T& cantFail(Expected<T&> ValOrErr) {
+T& cantFail(Expected<T&> ValOrErr, const char *Msg = nullptr) {
   if (ValOrErr)
     return *ValOrErr;
-  else
-    llvm_unreachable("Failure value returned from cantFail wrapped call");
+  else {
+    if (!Msg)
+      Msg = "Failure value returned from cantFail wrapped call";
+    llvm_unreachable(Msg);
+  }
 }
 
 /// Helper for testing applicability of, and applying, handlers for
@@ -775,7 +784,7 @@ public:
   }
 };
 
-/// Specialization for functions of the form 'Error (std::unique_ptr<ErrT>)'.
+/// Specialization for functions of the form 'void (std::unique_ptr<ErrT>)'.
 template <typename ErrT>
 class ErrorHandlerTraits<void (&)(std::unique_ptr<ErrT>)> {
 public:
@@ -813,7 +822,7 @@ class ErrorHandlerTraits<RetT (C::*)(const ErrT &) const>
     : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
 
 /// Specialization for member functions of the form
-/// 'RetT (std::unique_ptr<ErrT>) const'.
+/// 'RetT (std::unique_ptr<ErrT>)'.
 template <typename C, typename RetT, typename ErrT>
 class ErrorHandlerTraits<RetT (C::*)(std::unique_ptr<ErrT>)>
     : public ErrorHandlerTraits<RetT (&)(std::unique_ptr<ErrT>)> {};
index db332ebff7a2cb82a33925d1cd1a4972bac8523a..6010122a9a007595802e95454627a8f1de2a199f 100644 (file)
@@ -486,8 +486,9 @@ TEST(Error, CantFailSuccess) {
 #if LLVM_ENABLE_ABI_BREAKING_CHECKS && !defined(NDEBUG)
 TEST(Error, CantFailDeath) {
   EXPECT_DEATH(
-      cantFail(make_error<StringError>("foo", inconvertibleErrorCode())),
-      "Failure value returned from cantFail wrapped call")
+      cantFail(make_error<StringError>("foo", inconvertibleErrorCode()),
+               "Cantfail call failed"),
+      "Cantfail call failed")
     << "cantFail(Error) did not cause an abort for failure value";
 
   EXPECT_DEATH(