diff --git a/include/llvm/Support/Error.h b/include/llvm/Support/Error.h index 04d6132bb7f..113a123e4a5 100644 --- a/include/llvm/Support/Error.h +++ b/include/llvm/Support/Error.h @@ -627,7 +627,7 @@ public: Checked(false) #endif { - new (getStorage()) storage_type(std::move(Val)); + new (getStorage()) storage_type(std::forward(Val)); } /// Move construct an Expected 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 T operator()(Expected &&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 T& operator()(Expected &&E) const { + checkError(E.takeError()); + return *E; + } + private: void checkError(Error Err) const { if (Err) { diff --git a/unittests/Support/ErrorTest.cpp b/unittests/Support/ErrorTest.cpp index 6a1400aa540..f7e3b398c87 100644 --- a/unittests/Support/ErrorTest.cpp +++ b/unittests/Support/ErrorTest.cpp @@ -391,6 +391,10 @@ TEST(Error, ExitOnError) { EXPECT_EQ(ExitOnErr(Expected(7)), 7) << "exitOnError returned an invalid value for Expected"; + int A = 7; + int &B = ExitOnErr(Expected(A)); + EXPECT_EQ(&A, &B) << "ExitOnError failed to propagate reference"; + // Exit tests. EXPECT_EXIT(ExitOnErr(make_error(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 B = A; + // 'Check' B. + (void)!!B; + int &C = *B; + EXPECT_EQ(&A, &C) << "Expected failed to propagate reference"; +} + // Test Unchecked Expected in success mode. // We expect this to blow up the same way Error would. // Test runs in debug mode only.