diff options
author | Lang Hames <lhames@gmail.com> | 2016-04-05 19:57:03 +0000 |
---|---|---|
committer | Lang Hames <lhames@gmail.com> | 2016-04-05 19:57:03 +0000 |
commit | 580ca237db3db87264b44758a89d97a7bb445ff1 (patch) | |
tree | 01142eb14ff06a0b8a302f9620a8a777ac42e911 /llvm/unittests/Support/ErrorTest.cpp | |
parent | bdc3b4d5230fcaace4101e6f4a664cd01828a46a (diff) | |
download | bcm5719-llvm-580ca237db3db87264b44758a89d97a7bb445ff1.tar.gz bcm5719-llvm-580ca237db3db87264b44758a89d97a7bb445ff1.zip |
[Support] Add a checked flag to Expected<T>, require checks before access or
destruction.
This makes the Expected<T> class behave like Error, even when in success mode.
Expected<T> values must be checked to see whether they contain an error prior
to being dereferenced, assigned to, or destructed.
llvm-svn: 265446
Diffstat (limited to 'llvm/unittests/Support/ErrorTest.cpp')
-rw-r--r-- | llvm/unittests/Support/ErrorTest.cpp | 50 |
1 files changed, 46 insertions, 4 deletions
diff --git a/llvm/unittests/Support/ErrorTest.cpp b/llvm/unittests/Support/ErrorTest.cpp index 7d714777c65..6a1400aa540 100644 --- a/llvm/unittests/Support/ErrorTest.cpp +++ b/llvm/unittests/Support/ErrorTest.cpp @@ -401,13 +401,47 @@ TEST(Error, ExitOnError) { << "exitOnError returned an unexpected error result"; } -// Test Expected<T> in success mode. -TEST(Error, ExpectedInSuccessMode) { +// Test Checked Expected<T> in success mode. +TEST(Error, CheckedExpectedInSuccessMode) { Expected<int> A = 7; EXPECT_TRUE(!!A) << "Expected with non-error value doesn't convert to 'true'"; + // Access is safe in second test, since we checked the error in the first. EXPECT_EQ(*A, 7) << "Incorrect Expected non-error value"; } +// Test Unchecked Expected<T> in success mode. +// We expect this to blow up the same way Error would. +// Test runs in debug mode only. +#ifndef NDEBUG +TEST(Error, UncheckedExpectedInSuccessModeDestruction) { + EXPECT_DEATH({ Expected<int> A = 7; }, + "Expected<T> must be checked before access or destruction.") + << "Unchecekd Expected<T> success value did not cause an abort()."; +} +#endif + +// Test Unchecked Expected<T> in success mode. +// We expect this to blow up the same way Error would. +// Test runs in debug mode only. +#ifndef NDEBUG +TEST(Error, UncheckedExpectedInSuccessModeAccess) { + EXPECT_DEATH({ Expected<int> A = 7; *A; }, + "Expected<T> must be checked before access or destruction.") + << "Unchecekd Expected<T> success value did not cause an abort()."; +} +#endif + +// Test Unchecked Expected<T> in success mode. +// We expect this to blow up the same way Error would. +// Test runs in debug mode only. +#ifndef NDEBUG +TEST(Error, UncheckedExpectedInSuccessModeAssignment) { + EXPECT_DEATH({ Expected<int> A = 7; A = 7; }, + "Expected<T> must be checked before access or destruction.") + << "Unchecekd Expected<T> success value did not cause an abort()."; +} +#endif + // Test Expected<T> in failure mode. TEST(Error, ExpectedInFailureMode) { Expected<int> A = make_error<CustomError>(42); @@ -423,7 +457,7 @@ TEST(Error, ExpectedInFailureMode) { #ifndef NDEBUG TEST(Error, AccessExpectedInFailureMode) { Expected<int> A = make_error<CustomError>(42); - EXPECT_DEATH(*A, "!HasError && \"Cannot get value when an error exists!\"") + EXPECT_DEATH(*A, "Expected<T> must be checked before access or destruction.") << "Incorrect Expected error value"; consumeError(A.takeError()); } @@ -435,7 +469,7 @@ TEST(Error, AccessExpectedInFailureMode) { #ifndef NDEBUG TEST(Error, UnhandledExpectedInFailureMode) { EXPECT_DEATH({ Expected<int> A = make_error<CustomError>(42); }, - "Program aborted due to an unhandled Error:") + "Expected<T> must be checked before access or destruction.") << "Unchecked Expected<T> failure value did not cause an abort()"; } #endif @@ -446,10 +480,18 @@ TEST(Error, ExpectedCovariance) { class D : public B {}; Expected<B *> A1(Expected<D *>(nullptr)); + // Check A1 by converting to bool before assigning to it. + (void)!!A1; A1 = Expected<D *>(nullptr); + // Check A1 again before destruction. + (void)!!A1; Expected<std::unique_ptr<B>> A2(Expected<std::unique_ptr<D>>(nullptr)); + // Check A2 by converting to bool before assigning to it. + (void)!!A2; A2 = Expected<std::unique_ptr<D>>(nullptr); + // Check A2 again before destruction. + (void)!!A2; } TEST(Error, ErrorCodeConversions) { |