blob: 1807547572ba809046ab790df6001102131a7abf [file] [log] [blame]
Lang Hamesf7f6d3e2016-03-16 01:02:46 +00001//===----- unittests/ErrorTest.cpp - Error.h tests ------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "llvm/Support/Error.h"
11#include "llvm/Support/Errc.h"
Lang Hamese7aad352016-03-23 23:57:28 +000012#include "llvm/Support/ErrorHandling.h"
Lang Hamesf7f6d3e2016-03-16 01:02:46 +000013#include "gtest/gtest.h"
14#include <memory>
15
16using namespace llvm;
17
18namespace {
19
Lang Hamesf7f6d3e2016-03-16 01:02:46 +000020// Custom error class with a default base class and some random 'info' attached.
21class CustomError : public ErrorInfo<CustomError> {
22public:
23 // Create an error with some info attached.
24 CustomError(int Info) : Info(Info) {}
25
26 // Get the info attached to this error.
27 int getInfo() const { return Info; }
28
29 // Log this error to a stream.
30 void log(raw_ostream &OS) const override {
31 OS << "CustomError { " << getInfo() << "}";
32 }
33
Lang Hamese7aad352016-03-23 23:57:28 +000034 std::error_code convertToErrorCode() const override {
35 llvm_unreachable("CustomError doesn't support ECError conversion");
36 }
37
Lang Hamesf7f6d3e2016-03-16 01:02:46 +000038protected:
39 // This error is subclassed below, but we can't use inheriting constructors
40 // yet, so we can't propagate the constructors through ErrorInfo. Instead
41 // we have to have a default constructor and have the subclass initialize all
42 // fields.
43 CustomError() : Info(0) {}
44
45 int Info;
46};
47
48// Custom error class with a custom base class and some additional random
49// 'info'.
50class CustomSubError : public ErrorInfo<CustomSubError, CustomError> {
51public:
52 // Create a sub-error with some info attached.
53 CustomSubError(int Info, int ExtraInfo) : ExtraInfo(ExtraInfo) {
54 this->Info = Info;
55 }
56
57 // Get the extra info attached to this error.
58 int getExtraInfo() const { return ExtraInfo; }
59
60 // Log this error to a stream.
61 void log(raw_ostream &OS) const override {
62 OS << "CustomSubError { " << getInfo() << ", " << getExtraInfo() << "}";
63 }
64
Lang Hamese7aad352016-03-23 23:57:28 +000065 std::error_code convertToErrorCode() const override {
66 llvm_unreachable("CustomSubError doesn't support ECError conversion");
67 }
68
Lang Hamesf7f6d3e2016-03-16 01:02:46 +000069protected:
70 int ExtraInfo;
71};
72
Lang Hamesf7f6d3e2016-03-16 01:02:46 +000073static Error handleCustomError(const CustomError &CE) { return Error(); }
74
75static void handleCustomErrorVoid(const CustomError &CE) {}
76
77static Error handleCustomErrorUP(std::unique_ptr<CustomError> CE) {
78 return Error();
79}
80
81static void handleCustomErrorUPVoid(std::unique_ptr<CustomError> CE) {}
82
Lang Hames01864a22016-03-18 00:12:37 +000083// Test that success values implicitly convert to false, and don't cause crashes
84// once they've been implicitly converted.
85TEST(Error, CheckedSuccess) {
86 Error E;
87 EXPECT_FALSE(E) << "Unexpected error while testing Error 'Success'";
88}
89
90// Test that unchecked succes values cause an abort.
91#ifndef NDEBUG
92TEST(Error, UncheckedSuccess) {
93 EXPECT_DEATH({ Error E; }, "Program aborted due to an unhandled Error:")
94 << "Unchecked Error Succes value did not cause abort()";
95}
96#endif
97
Lang Hamesf7f6d3e2016-03-16 01:02:46 +000098// Check that we abort on unhandled failure cases. (Force conversion to bool
99// to make sure that we don't accidentally treat checked errors as handled).
100// Test runs in debug mode only.
101#ifndef NDEBUG
Lang Hames01864a22016-03-18 00:12:37 +0000102TEST(Error, UncheckedError) {
103 auto DropUnhandledError = []() {
104 Error E = make_error<CustomError>(42);
105 (void)!E;
106 };
107 EXPECT_DEATH(DropUnhandledError(),
108 "Program aborted due to an unhandled Error:")
109 << "Unhandled Error failure value did not cause abort()";
110}
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000111#endif
112
Lang Hames01864a22016-03-18 00:12:37 +0000113// Check 'Error::isA<T>' method handling.
114TEST(Error, IsAHandling) {
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000115 // Check 'isA' handling.
Lang Hames01864a22016-03-18 00:12:37 +0000116 Error E = make_error<CustomError>(1);
117 Error F = make_error<CustomSubError>(1, 2);
118 Error G = Error::success();
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000119
Lang Hames01864a22016-03-18 00:12:37 +0000120 EXPECT_TRUE(E.isA<CustomError>());
121 EXPECT_FALSE(E.isA<CustomSubError>());
122 EXPECT_TRUE(F.isA<CustomError>());
123 EXPECT_TRUE(F.isA<CustomSubError>());
124 EXPECT_FALSE(G.isA<CustomError>());
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000125
Lang Hames01864a22016-03-18 00:12:37 +0000126 consumeError(std::move(E));
127 consumeError(std::move(F));
128 consumeError(std::move(G));
129}
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000130
Lang Hames01864a22016-03-18 00:12:37 +0000131// Check that we can handle a custom error.
132TEST(Error, HandleCustomError) {
133 int CaughtErrorInfo = 0;
134 handleAllErrors(make_error<CustomError>(42), [&](const CustomError &CE) {
135 CaughtErrorInfo = CE.getInfo();
136 });
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000137
Lang Hames01864a22016-03-18 00:12:37 +0000138 EXPECT_TRUE(CaughtErrorInfo == 42) << "Wrong result from CustomError handler";
139}
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000140
Lang Hames01864a22016-03-18 00:12:37 +0000141// Check that handler type deduction also works for handlers
142// of the following types:
143// void (const Err&)
144// Error (const Err&) mutable
145// void (const Err&) mutable
146// Error (Err&)
147// void (Err&)
148// Error (Err&) mutable
149// void (Err&) mutable
150// Error (unique_ptr<Err>)
151// void (unique_ptr<Err>)
152// Error (unique_ptr<Err>) mutable
153// void (unique_ptr<Err>) mutable
154TEST(Error, HandlerTypeDeduction) {
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000155
156 handleAllErrors(make_error<CustomError>(42), [](const CustomError &CE) {});
157
158 handleAllErrors(
159 make_error<CustomError>(42),
160 [](const CustomError &CE) mutable { return Error::success(); });
161
162 handleAllErrors(make_error<CustomError>(42),
163 [](const CustomError &CE) mutable {});
164
165 handleAllErrors(make_error<CustomError>(42),
166 [](CustomError &CE) { return Error::success(); });
167
168 handleAllErrors(make_error<CustomError>(42), [](CustomError &CE) {});
169
170 handleAllErrors(make_error<CustomError>(42),
171 [](CustomError &CE) mutable { return Error::success(); });
172
173 handleAllErrors(make_error<CustomError>(42), [](CustomError &CE) mutable {});
174
175 handleAllErrors(
176 make_error<CustomError>(42),
177 [](std::unique_ptr<CustomError> CE) { return Error::success(); });
178
179 handleAllErrors(make_error<CustomError>(42),
180 [](std::unique_ptr<CustomError> CE) {});
181
182 handleAllErrors(
183 make_error<CustomError>(42),
184 [](std::unique_ptr<CustomError> CE) mutable { return Error::success(); });
185
186 handleAllErrors(make_error<CustomError>(42),
187 [](std::unique_ptr<CustomError> CE) mutable {});
188
189 // Check that named handlers of type 'Error (const Err&)' work.
190 handleAllErrors(make_error<CustomError>(42), handleCustomError);
191
192 // Check that named handlers of type 'void (const Err&)' work.
193 handleAllErrors(make_error<CustomError>(42), handleCustomErrorVoid);
194
195 // Check that named handlers of type 'Error (std::unique_ptr<Err>)' work.
196 handleAllErrors(make_error<CustomError>(42), handleCustomErrorUP);
197
198 // Check that named handlers of type 'Error (std::unique_ptr<Err>)' work.
199 handleAllErrors(make_error<CustomError>(42), handleCustomErrorUPVoid);
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000200}
201
Lang Hames01864a22016-03-18 00:12:37 +0000202// Test that we can handle errors with custom base classes.
203TEST(Error, HandleCustomErrorWithCustomBaseClass) {
204 int CaughtErrorInfo = 0;
205 int CaughtErrorExtraInfo = 0;
206 handleAllErrors(make_error<CustomSubError>(42, 7),
207 [&](const CustomSubError &SE) {
208 CaughtErrorInfo = SE.getInfo();
209 CaughtErrorExtraInfo = SE.getExtraInfo();
210 });
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000211
Lang Hames01864a22016-03-18 00:12:37 +0000212 EXPECT_TRUE(CaughtErrorInfo == 42 && CaughtErrorExtraInfo == 7)
213 << "Wrong result from CustomSubError handler";
214}
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000215
Lang Hames01864a22016-03-18 00:12:37 +0000216// Check that we trigger only the first handler that applies.
217TEST(Error, FirstHandlerOnly) {
218 int DummyInfo = 0;
219 int CaughtErrorInfo = 0;
220 int CaughtErrorExtraInfo = 0;
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000221
Lang Hames01864a22016-03-18 00:12:37 +0000222 handleAllErrors(make_error<CustomSubError>(42, 7),
223 [&](const CustomSubError &SE) {
224 CaughtErrorInfo = SE.getInfo();
225 CaughtErrorExtraInfo = SE.getExtraInfo();
226 },
227 [&](const CustomError &CE) { DummyInfo = CE.getInfo(); });
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000228
Lang Hames01864a22016-03-18 00:12:37 +0000229 EXPECT_TRUE(CaughtErrorInfo == 42 && CaughtErrorExtraInfo == 7 &&
230 DummyInfo == 0)
231 << "Activated the wrong Error handler(s)";
232}
233
234// Check that general handlers shadow specific ones.
235TEST(Error, HandlerShadowing) {
236 int CaughtErrorInfo = 0;
237 int DummyInfo = 0;
238 int DummyExtraInfo = 0;
239
240 handleAllErrors(
241 make_error<CustomSubError>(42, 7),
242 [&](const CustomError &CE) { CaughtErrorInfo = CE.getInfo(); },
243 [&](const CustomSubError &SE) {
244 DummyInfo = SE.getInfo();
245 DummyExtraInfo = SE.getExtraInfo();
246 });
247
248 EXPECT_TRUE(CaughtErrorInfo = 42 && DummyInfo == 0 && DummyExtraInfo == 0)
249 << "General Error handler did not shadow specific handler";
250}
251
252// Test joinErrors.
253TEST(Error, CheckJoinErrors) {
254 int CustomErrorInfo1 = 0;
255 int CustomErrorInfo2 = 0;
256 int CustomErrorExtraInfo = 0;
257 Error E =
258 joinErrors(make_error<CustomError>(7), make_error<CustomSubError>(42, 7));
259
260 handleAllErrors(std::move(E),
261 [&](const CustomSubError &SE) {
262 CustomErrorInfo2 = SE.getInfo();
263 CustomErrorExtraInfo = SE.getExtraInfo();
264 },
265 [&](const CustomError &CE) {
266 // Assert that the CustomError instance above is handled
267 // before the
268 // CustomSubError - joinErrors should preserve error
269 // ordering.
270 EXPECT_EQ(CustomErrorInfo2, 0)
271 << "CustomErrorInfo2 should be 0 here. "
272 "joinErrors failed to preserve ordering.\n";
273 CustomErrorInfo1 = CE.getInfo();
274 });
275
276 EXPECT_TRUE(CustomErrorInfo1 == 7 && CustomErrorInfo2 == 42 &&
277 CustomErrorExtraInfo == 7)
278 << "Failed handling compound Error.";
279}
280
281// Test that we can consume success values.
282TEST(Error, ConsumeSuccess) {
283 Error E;
284 consumeError(std::move(E));
285}
286
287TEST(Error, ConsumeError) {
288 Error E = make_error<CustomError>(7);
289 consumeError(std::move(E));
290}
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000291
292// Test that handleAllUnhandledErrors crashes if an error is not caught.
293// Test runs in debug mode only.
294#ifndef NDEBUG
Lang Hames01864a22016-03-18 00:12:37 +0000295TEST(Error, FailureToHandle) {
296 auto FailToHandle = []() {
297 handleAllErrors(make_error<CustomError>(7), [&](const CustomSubError &SE) {
298 errs() << "This should never be called";
299 exit(1);
300 });
301 };
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000302
Lang Hames01864a22016-03-18 00:12:37 +0000303 EXPECT_DEATH(FailToHandle(), "Program aborted due to an unhandled Error:")
304 << "Unhandled Error in handleAllErrors call did not cause an "
305 "abort()";
306}
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000307#endif
308
309// Test that handleAllUnhandledErrors crashes if an error is returned from a
310// handler.
311// Test runs in debug mode only.
312#ifndef NDEBUG
Lang Hames01864a22016-03-18 00:12:37 +0000313TEST(Error, FailureFromHandler) {
314 auto ReturnErrorFromHandler = []() {
315 handleAllErrors(make_error<CustomError>(7),
316 [&](std::unique_ptr<CustomSubError> SE) {
317 return Error(std::move(SE));
318 });
319 };
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000320
Lang Hames01864a22016-03-18 00:12:37 +0000321 EXPECT_DEATH(ReturnErrorFromHandler(),
322 "Program aborted due to an unhandled Error:")
323 << " Error returned from handler in handleAllErrors call did not "
324 "cause abort()";
325}
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000326#endif
327
Lang Hames01864a22016-03-18 00:12:37 +0000328// Test that we can return values from handleErrors.
329TEST(Error, CatchErrorFromHandler) {
330 int ErrorInfo = 0;
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000331
Lang Hames01864a22016-03-18 00:12:37 +0000332 Error E = handleErrors(
333 make_error<CustomError>(7),
334 [&](std::unique_ptr<CustomError> CE) { return Error(std::move(CE)); });
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000335
Lang Hames01864a22016-03-18 00:12:37 +0000336 handleAllErrors(std::move(E),
337 [&](const CustomError &CE) { ErrorInfo = CE.getInfo(); });
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000338
Lang Hames01864a22016-03-18 00:12:37 +0000339 EXPECT_EQ(ErrorInfo, 7)
340 << "Failed to handle Error returned from handleErrors.";
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000341}
342
Lang Hames01864a22016-03-18 00:12:37 +0000343// Test that the ExitOnError utility works as expected.
344TEST(Error, ExitOnError) {
345 ExitOnError ExitOnErr;
346 ExitOnErr.setBanner("Error in tool:");
347 ExitOnErr.setExitCodeMapper([](const Error &E) {
348 if (E.isA<CustomSubError>())
349 return 2;
350 return 1;
351 });
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000352
Lang Hames01864a22016-03-18 00:12:37 +0000353 // Make sure we don't bail on success.
354 ExitOnErr(Error::success());
355 EXPECT_EQ(ExitOnErr(Expected<int>(7)), 7)
356 << "exitOnError returned an invalid value for Expected";
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000357
Lang Hames01864a22016-03-18 00:12:37 +0000358 // Exit tests.
359 EXPECT_EXIT(ExitOnErr(make_error<CustomError>(7)),
360 ::testing::ExitedWithCode(1), "Error in tool:")
361 << "exitOnError returned an unexpected error result";
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000362
Lang Hames01864a22016-03-18 00:12:37 +0000363 EXPECT_EXIT(ExitOnErr(Expected<int>(make_error<CustomSubError>(0, 0))),
364 ::testing::ExitedWithCode(2), "Error in tool:")
365 << "exitOnError returned an unexpected error result";
366}
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000367
Lang Hames01864a22016-03-18 00:12:37 +0000368// Test Expected<T> in success mode.
369TEST(Error, ExpectedInSuccessMode) {
370 Expected<int> A = 7;
371 EXPECT_TRUE(!!A) << "Expected with non-error value doesn't convert to 'true'";
372 EXPECT_EQ(*A, 7) << "Incorrect Expected non-error value";
373}
374
375// Test Expected<T> in failure mode.
376TEST(Error, ExpectedInFailureMode) {
377 Expected<int> A = make_error<CustomError>(42);
378 EXPECT_FALSE(!!A) << "Expected with error value doesn't convert to 'false'";
379 Error E = A.takeError();
380 EXPECT_TRUE(E.isA<CustomError>()) << "Incorrect Expected error value";
381 consumeError(std::move(E));
382}
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000383
384// Check that an Expected instance with an error value doesn't allow access to
385// operator*.
386// Test runs in debug mode only.
387#ifndef NDEBUG
Lang Hames01864a22016-03-18 00:12:37 +0000388TEST(Error, AccessExpectedInFailureMode) {
389 Expected<int> A = make_error<CustomError>(42);
390 EXPECT_DEATH(*A, "!HasError && \"Cannot get value when an error exists!\"")
391 << "Incorrect Expected error value";
392 consumeError(A.takeError());
393}
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000394#endif
395
396// Check that an Expected instance with an error triggers an abort if
397// unhandled.
398// Test runs in debug mode only.
399#ifndef NDEBUG
Lang Hames01864a22016-03-18 00:12:37 +0000400TEST(Error, UnhandledExpectedInFailureMode) {
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000401 EXPECT_DEATH({ Expected<int> A = make_error<CustomError>(42); },
402 "Program aborted due to an unhandled Error:")
403 << "Unchecked Expected<T> failure value did not cause an abort()";
Lang Hames01864a22016-03-18 00:12:37 +0000404}
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000405#endif
406
Lang Hames01864a22016-03-18 00:12:37 +0000407// Test covariance of Expected.
408TEST(Error, ExpectedCovariance) {
409 class B {};
410 class D : public B {};
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000411
Lang Hames01864a22016-03-18 00:12:37 +0000412 Expected<B *> A1(Expected<D *>(nullptr));
413 A1 = Expected<D *>(nullptr);
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000414
Lang Hames01864a22016-03-18 00:12:37 +0000415 Expected<std::unique_ptr<B>> A2(Expected<std::unique_ptr<D>>(nullptr));
416 A2 = Expected<std::unique_ptr<D>>(nullptr);
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000417}
418
419TEST(Error, ECError) {
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000420 // Round-trip a success value to check that it converts correctly.
421 EXPECT_EQ(errorToErrorCode(errorCodeToError(std::error_code())),
422 std::error_code())
423 << "std::error_code() should round-trip via Error conversions";
424
425 // Round-trip an error value to check that it converts correctly.
426 EXPECT_EQ(errorToErrorCode(errorCodeToError(errc::invalid_argument)),
427 errc::invalid_argument)
428 << "std::error_code error value should round-trip via Error "
429 "conversions";
430}
431
432} // end anon namespace