aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests/Support/ErrorTest.cpp
diff options
context:
space:
mode:
authorLang Hames <lhames@gmail.com>2016-03-17 21:28:49 +0000
committerLang Hames <lhames@gmail.com>2016-03-17 21:28:49 +0000
commit6935c2d3227661bda111bdecae976a091b8307d8 (patch)
tree936675c00ce2c608a996488e45ba4bda358108f2 /llvm/unittests/Support/ErrorTest.cpp
parent016b2d0ddc4855a2e07161abd9ba6cdcebadd0c4 (diff)
downloadllvm-6935c2d3227661bda111bdecae976a091b8307d8.zip
llvm-6935c2d3227661bda111bdecae976a091b8307d8.tar.gz
llvm-6935c2d3227661bda111bdecae976a091b8307d8.tar.bz2
[Support] Add ExitOnError utility to support tools that use the exit-on-error
idiom. Most LLVM tool code exits immediately when an error is encountered and prints an error message to stderr. The ExitOnError class supports this by providing two call operators - one for Errors, and one for Expected<T>s. Calls to code that can return Errors (or Expected<T>s) can use these calls to bail out on error, and otherwise continue as if the operation had succeeded. E.g. Error foo(); Expected<int> bar(); int main(int argc, char *argv[]) { ExitOnError ExitOnErr; ExitOnErr.setBanner(std::string("Error in ") + argv[0] + ":"); // Exit if foo returns an error. No need to manually check error return. ExitOnErr(foo()); // Exit if bar returns an error, otherwise unwrap the contained int and // continue. int X = ExitOnErr(bar()); // ... return 0; } llvm-svn: 263749
Diffstat (limited to 'llvm/unittests/Support/ErrorTest.cpp')
-rw-r--r--llvm/unittests/Support/ErrorTest.cpp28
1 files changed, 28 insertions, 0 deletions
diff --git a/llvm/unittests/Support/ErrorTest.cpp b/llvm/unittests/Support/ErrorTest.cpp
index d5af2ca..343a2d2 100644
--- a/llvm/unittests/Support/ErrorTest.cpp
+++ b/llvm/unittests/Support/ErrorTest.cpp
@@ -38,6 +38,7 @@ namespace {
// - consume_error to consume a "safe" error without any output.
// - handleAllUnhandledErrors to assert that all errors are handled.
// - logAllUnhandledErrors to log errors to a stream.
+// - ExitOnError tests.
//
// Expected tests:
// - Expected<T> with T.
@@ -50,6 +51,7 @@ namespace {
// - std::error_code to Error (ECError) in failure mode.
// - Error to std::error_code in success mode.
// - Error (ECError) to std::error_code in failure mode.
+//
// Custom error class with a default base class and some random 'info' attached.
class CustomError : public ErrorInfo<CustomError> {
@@ -376,6 +378,32 @@ TEST(Error, CheckErrorUtilities) {
EXPECT_EQ(ErrorInfo, 7)
<< "Failed to handle Error returned from handleErrors.";
}
+
+ // Test ExitOnError
+ {
+ ExitOnError ExitOnErr;
+ ExitOnErr.setBanner("Error in tool:");
+ ExitOnErr.setExitCodeMapper(
+ [](const Error &E) {
+ if (E.isA<CustomSubError>())
+ return 2;
+ return 1;
+ });
+
+ // Make sure we don't bail on success.
+ ExitOnErr(Error::success());
+ EXPECT_EQ(ExitOnErr(Expected<int>(7)), 7)
+ << "exitOnError returned an invalid value for Expected";
+
+ // Exit tests.
+ EXPECT_EXIT(ExitOnErr(make_error<CustomError>(7)),
+ ::testing::ExitedWithCode(1), "Error in tool:")
+ << "exitOnError returned an unexpected error result";
+
+ EXPECT_EXIT(ExitOnErr(Expected<int>(make_error<CustomSubError>(0, 0))),
+ ::testing::ExitedWithCode(2), "Error in tool:")
+ << "exitOnError returned an unexpected error result";
+ }
}
// Test Expected behavior.