[llvm] r267448 - [Support] Fix latent bugs in Expected and ExitOnError that were preventing them

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 25 12:21:57 PDT 2016


Author: lhames
Date: Mon Apr 25 14:21:57 2016
New Revision: 267448

URL: http://llvm.org/viewvc/llvm-project?rev=267448&view=rev
Log:
[Support] Fix latent bugs in Expected and ExitOnError that were preventing them
from working with reference types.

Modified:
    llvm/trunk/include/llvm/Support/Error.h
    llvm/trunk/unittests/Support/ErrorTest.cpp

Modified: llvm/trunk/include/llvm/Support/Error.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Error.h?rev=267448&r1=267447&r2=267448&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/Error.h (original)
+++ llvm/trunk/include/llvm/Support/Error.h Mon Apr 25 14:21:57 2016
@@ -627,7 +627,7 @@ public:
         Checked(false)
 #endif
   {
-    new (getStorage()) storage_type(std::move(Val));
+    new (getStorage()) storage_type(std::forward<OtherT>(Val));
   }
 
   /// Move construct an Expected<T> value.
@@ -886,13 +886,20 @@ public:
   /// Check Err. If it's in a failure state log the error(s) and exit.
   void operator()(Error Err) const { checkError(std::move(Err)); }
 
-  /// Check E. If it's in a success state return the contained value. If it's
-  /// in a failure state log the error(s) and exit.
+  /// Check E. If it's in a success state then return the contained value. If
+  /// it's in a failure state log the error(s) and exit.
   template <typename T> T operator()(Expected<T> &&E) const {
     checkError(E.takeError());
     return std::move(*E);
   }
 
+  /// Check E. If it's in a success state then return the contained reference. If
+  /// it's in a failure state log the error(s) and exit.
+  template <typename T> T& operator()(Expected<T&> &&E) const {
+    checkError(E.takeError());
+    return *E;
+  }
+
 private:
   void checkError(Error Err) const {
     if (Err) {

Modified: llvm/trunk/unittests/Support/ErrorTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/ErrorTest.cpp?rev=267448&r1=267447&r2=267448&view=diff
==============================================================================
--- llvm/trunk/unittests/Support/ErrorTest.cpp (original)
+++ llvm/trunk/unittests/Support/ErrorTest.cpp Mon Apr 25 14:21:57 2016
@@ -391,6 +391,10 @@ TEST(Error, ExitOnError) {
   EXPECT_EQ(ExitOnErr(Expected<int>(7)), 7)
       << "exitOnError returned an invalid value for Expected";
 
+  int A = 7;
+  int &B = ExitOnErr(Expected<int&>(A));
+  EXPECT_EQ(&A, &B) << "ExitOnError failed to propagate reference";
+
   // Exit tests.
   EXPECT_EXIT(ExitOnErr(make_error<CustomError>(7)),
               ::testing::ExitedWithCode(1), "Error in tool:")
@@ -409,6 +413,16 @@ TEST(Error, CheckedExpectedInSuccessMode
   EXPECT_EQ(*A, 7) << "Incorrect Expected non-error value";
 }
 
+// Test Expected with reference type.
+TEST(Error, ExpectedWithReferenceType) {
+  int A = 7;
+  Expected<int&> B = A;
+  // 'Check' B.
+  (void)!!B;
+  int &C = *B;
+  EXPECT_EQ(&A, &C) << "Expected failed to propagate reference";
+}
+
 // Test Unchecked Expected<T> in success mode.
 // We expect this to blow up the same way Error would.
 // Test runs in debug mode only.




More information about the llvm-commits mailing list