blob: 6010122a9a007595802e95454627a8f1de2a199f [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"
Lang Hamesc5e0bbd2016-05-27 01:37:32 +000011
12#include "llvm/ADT/Twine.h"
Lang Hamesf7f6d3e2016-03-16 01:02:46 +000013#include "llvm/Support/Errc.h"
Lang Hamese7aad352016-03-23 23:57:28 +000014#include "llvm/Support/ErrorHandling.h"
Lang Hamesf7f6d3e2016-03-16 01:02:46 +000015#include "gtest/gtest.h"
16#include <memory>
17
18using namespace llvm;
19
20namespace {
21
Lang Hamesf7f6d3e2016-03-16 01:02:46 +000022// Custom error class with a default base class and some random 'info' attached.
23class CustomError : public ErrorInfo<CustomError> {
24public:
25 // Create an error with some info attached.
26 CustomError(int Info) : Info(Info) {}
27
28 // Get the info attached to this error.
29 int getInfo() const { return Info; }
30
31 // Log this error to a stream.
32 void log(raw_ostream &OS) const override {
33 OS << "CustomError { " << getInfo() << "}";
34 }
35
Lang Hamese7aad352016-03-23 23:57:28 +000036 std::error_code convertToErrorCode() const override {
37 llvm_unreachable("CustomError doesn't support ECError conversion");
38 }
39
Reid Klecknera15b76b2016-03-24 23:49:34 +000040 // Used by ErrorInfo::classID.
41 static char ID;
42
Lang Hamesf7f6d3e2016-03-16 01:02:46 +000043protected:
44 // This error is subclassed below, but we can't use inheriting constructors
45 // yet, so we can't propagate the constructors through ErrorInfo. Instead
46 // we have to have a default constructor and have the subclass initialize all
47 // fields.
48 CustomError() : Info(0) {}
49
50 int Info;
51};
52
Reid Klecknera15b76b2016-03-24 23:49:34 +000053char CustomError::ID = 0;
54
Lang Hamesf7f6d3e2016-03-16 01:02:46 +000055// Custom error class with a custom base class and some additional random
56// 'info'.
57class CustomSubError : public ErrorInfo<CustomSubError, CustomError> {
58public:
59 // Create a sub-error with some info attached.
60 CustomSubError(int Info, int ExtraInfo) : ExtraInfo(ExtraInfo) {
61 this->Info = Info;
62 }
63
64 // Get the extra info attached to this error.
65 int getExtraInfo() const { return ExtraInfo; }
66
67 // Log this error to a stream.
68 void log(raw_ostream &OS) const override {
69 OS << "CustomSubError { " << getInfo() << ", " << getExtraInfo() << "}";
70 }
71
Lang Hamese7aad352016-03-23 23:57:28 +000072 std::error_code convertToErrorCode() const override {
73 llvm_unreachable("CustomSubError doesn't support ECError conversion");
74 }
75
Reid Klecknera15b76b2016-03-24 23:49:34 +000076 // Used by ErrorInfo::classID.
77 static char ID;
78
Lang Hamesf7f6d3e2016-03-16 01:02:46 +000079protected:
80 int ExtraInfo;
81};
82
Reid Klecknera15b76b2016-03-24 23:49:34 +000083char CustomSubError::ID = 0;
84
Mehdi Amini41af4302016-11-11 04:28:40 +000085static Error handleCustomError(const CustomError &CE) {
86 return Error::success();
87}
Lang Hamesf7f6d3e2016-03-16 01:02:46 +000088
89static void handleCustomErrorVoid(const CustomError &CE) {}
90
91static Error handleCustomErrorUP(std::unique_ptr<CustomError> CE) {
Mehdi Amini41af4302016-11-11 04:28:40 +000092 return Error::success();
Lang Hamesf7f6d3e2016-03-16 01:02:46 +000093}
94
95static void handleCustomErrorUPVoid(std::unique_ptr<CustomError> CE) {}
96
Lang Hames01864a22016-03-18 00:12:37 +000097// Test that success values implicitly convert to false, and don't cause crashes
98// once they've been implicitly converted.
99TEST(Error, CheckedSuccess) {
Mehdi Aminic1edf562016-11-11 04:29:25 +0000100 Error E = Error::success();
Lang Hames01864a22016-03-18 00:12:37 +0000101 EXPECT_FALSE(E) << "Unexpected error while testing Error 'Success'";
102}
103
104// Test that unchecked succes values cause an abort.
Mehdi Aminicb79c072016-11-30 19:08:41 +0000105#if LLVM_ENABLE_ABI_BREAKING_CHECKS
Lang Hames01864a22016-03-18 00:12:37 +0000106TEST(Error, UncheckedSuccess) {
Mehdi Aminic1edf562016-11-11 04:29:25 +0000107 EXPECT_DEATH({ Error E = Error::success(); },
108 "Program aborted due to an unhandled Error:")
Lang Hames01864a22016-03-18 00:12:37 +0000109 << "Unchecked Error Succes value did not cause abort()";
110}
111#endif
112
Lang Hamesd1af8fc2016-03-25 23:54:32 +0000113// ErrorAsOutParameter tester.
114void errAsOutParamHelper(Error &Err) {
Lang Hames5e51a2e2016-07-22 16:11:25 +0000115 ErrorAsOutParameter ErrAsOutParam(&Err);
Lang Hamesd1af8fc2016-03-25 23:54:32 +0000116 // Verify that checked flag is raised - assignment should not crash.
117 Err = Error::success();
118 // Raise the checked bit manually - caller should still have to test the
119 // error.
120 (void)!!Err;
Lang Hamesd0ac31a2016-03-25 21:56:35 +0000121}
122
Lang Hamesd1af8fc2016-03-25 23:54:32 +0000123// Test that ErrorAsOutParameter sets the checked flag on construction.
124TEST(Error, ErrorAsOutParameterChecked) {
Mehdi Aminic1edf562016-11-11 04:29:25 +0000125 Error E = Error::success();
Lang Hamesd1af8fc2016-03-25 23:54:32 +0000126 errAsOutParamHelper(E);
127 (void)!!E;
128}
129
130// Test that ErrorAsOutParameter clears the checked flag on destruction.
Mehdi Aminicb79c072016-11-30 19:08:41 +0000131#if LLVM_ENABLE_ABI_BREAKING_CHECKS
Lang Hamesd1af8fc2016-03-25 23:54:32 +0000132TEST(Error, ErrorAsOutParameterUnchecked) {
Mehdi Aminic1edf562016-11-11 04:29:25 +0000133 EXPECT_DEATH({ Error E = Error::success(); errAsOutParamHelper(E); },
Lang Hamesd1af8fc2016-03-25 23:54:32 +0000134 "Program aborted due to an unhandled Error:")
135 << "ErrorAsOutParameter did not clear the checked flag on destruction.";
136}
137#endif
138
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000139// Check that we abort on unhandled failure cases. (Force conversion to bool
140// to make sure that we don't accidentally treat checked errors as handled).
141// Test runs in debug mode only.
Mehdi Aminicb79c072016-11-30 19:08:41 +0000142#if LLVM_ENABLE_ABI_BREAKING_CHECKS
Lang Hames01864a22016-03-18 00:12:37 +0000143TEST(Error, UncheckedError) {
144 auto DropUnhandledError = []() {
145 Error E = make_error<CustomError>(42);
146 (void)!E;
147 };
148 EXPECT_DEATH(DropUnhandledError(),
149 "Program aborted due to an unhandled Error:")
150 << "Unhandled Error failure value did not cause abort()";
151}
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000152#endif
153
Lang Hames01864a22016-03-18 00:12:37 +0000154// Check 'Error::isA<T>' method handling.
155TEST(Error, IsAHandling) {
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000156 // Check 'isA' handling.
Lang Hames01864a22016-03-18 00:12:37 +0000157 Error E = make_error<CustomError>(1);
158 Error F = make_error<CustomSubError>(1, 2);
159 Error G = Error::success();
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000160
Lang Hames01864a22016-03-18 00:12:37 +0000161 EXPECT_TRUE(E.isA<CustomError>());
162 EXPECT_FALSE(E.isA<CustomSubError>());
163 EXPECT_TRUE(F.isA<CustomError>());
164 EXPECT_TRUE(F.isA<CustomSubError>());
165 EXPECT_FALSE(G.isA<CustomError>());
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000166
Lang Hames01864a22016-03-18 00:12:37 +0000167 consumeError(std::move(E));
168 consumeError(std::move(F));
169 consumeError(std::move(G));
170}
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000171
Lang Hames01864a22016-03-18 00:12:37 +0000172// Check that we can handle a custom error.
173TEST(Error, HandleCustomError) {
174 int CaughtErrorInfo = 0;
175 handleAllErrors(make_error<CustomError>(42), [&](const CustomError &CE) {
176 CaughtErrorInfo = CE.getInfo();
177 });
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000178
Lang Hames01864a22016-03-18 00:12:37 +0000179 EXPECT_TRUE(CaughtErrorInfo == 42) << "Wrong result from CustomError handler";
180}
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000181
Lang Hames01864a22016-03-18 00:12:37 +0000182// Check that handler type deduction also works for handlers
183// of the following types:
184// void (const Err&)
185// Error (const Err&) mutable
186// void (const Err&) mutable
187// Error (Err&)
188// void (Err&)
189// Error (Err&) mutable
190// void (Err&) mutable
191// Error (unique_ptr<Err>)
192// void (unique_ptr<Err>)
193// Error (unique_ptr<Err>) mutable
194// void (unique_ptr<Err>) mutable
195TEST(Error, HandlerTypeDeduction) {
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000196
197 handleAllErrors(make_error<CustomError>(42), [](const CustomError &CE) {});
198
199 handleAllErrors(
200 make_error<CustomError>(42),
Mehdi Aminic1edf562016-11-11 04:29:25 +0000201 [](const CustomError &CE) mutable -> Error { return Error::success(); });
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000202
203 handleAllErrors(make_error<CustomError>(42),
204 [](const CustomError &CE) mutable {});
205
206 handleAllErrors(make_error<CustomError>(42),
Mehdi Aminic1edf562016-11-11 04:29:25 +0000207 [](CustomError &CE) -> Error { return Error::success(); });
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000208
209 handleAllErrors(make_error<CustomError>(42), [](CustomError &CE) {});
210
211 handleAllErrors(make_error<CustomError>(42),
Mehdi Aminic1edf562016-11-11 04:29:25 +0000212 [](CustomError &CE) mutable -> Error { return Error::success(); });
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000213
214 handleAllErrors(make_error<CustomError>(42), [](CustomError &CE) mutable {});
215
216 handleAllErrors(
217 make_error<CustomError>(42),
Mehdi Aminic1edf562016-11-11 04:29:25 +0000218 [](std::unique_ptr<CustomError> CE) -> Error { return Error::success(); });
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000219
220 handleAllErrors(make_error<CustomError>(42),
221 [](std::unique_ptr<CustomError> CE) {});
222
223 handleAllErrors(
224 make_error<CustomError>(42),
Mehdi Aminic1edf562016-11-11 04:29:25 +0000225 [](std::unique_ptr<CustomError> CE) mutable -> Error { return Error::success(); });
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000226
227 handleAllErrors(make_error<CustomError>(42),
228 [](std::unique_ptr<CustomError> CE) mutable {});
229
230 // Check that named handlers of type 'Error (const Err&)' work.
231 handleAllErrors(make_error<CustomError>(42), handleCustomError);
232
233 // Check that named handlers of type 'void (const Err&)' work.
234 handleAllErrors(make_error<CustomError>(42), handleCustomErrorVoid);
235
236 // Check that named handlers of type 'Error (std::unique_ptr<Err>)' work.
237 handleAllErrors(make_error<CustomError>(42), handleCustomErrorUP);
238
239 // Check that named handlers of type 'Error (std::unique_ptr<Err>)' work.
240 handleAllErrors(make_error<CustomError>(42), handleCustomErrorUPVoid);
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000241}
242
Lang Hames01864a22016-03-18 00:12:37 +0000243// Test that we can handle errors with custom base classes.
244TEST(Error, HandleCustomErrorWithCustomBaseClass) {
245 int CaughtErrorInfo = 0;
246 int CaughtErrorExtraInfo = 0;
247 handleAllErrors(make_error<CustomSubError>(42, 7),
248 [&](const CustomSubError &SE) {
249 CaughtErrorInfo = SE.getInfo();
250 CaughtErrorExtraInfo = SE.getExtraInfo();
251 });
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000252
Lang Hames01864a22016-03-18 00:12:37 +0000253 EXPECT_TRUE(CaughtErrorInfo == 42 && CaughtErrorExtraInfo == 7)
254 << "Wrong result from CustomSubError handler";
255}
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000256
Lang Hames01864a22016-03-18 00:12:37 +0000257// Check that we trigger only the first handler that applies.
258TEST(Error, FirstHandlerOnly) {
259 int DummyInfo = 0;
260 int CaughtErrorInfo = 0;
261 int CaughtErrorExtraInfo = 0;
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000262
Lang Hames01864a22016-03-18 00:12:37 +0000263 handleAllErrors(make_error<CustomSubError>(42, 7),
264 [&](const CustomSubError &SE) {
265 CaughtErrorInfo = SE.getInfo();
266 CaughtErrorExtraInfo = SE.getExtraInfo();
267 },
268 [&](const CustomError &CE) { DummyInfo = CE.getInfo(); });
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000269
Lang Hames01864a22016-03-18 00:12:37 +0000270 EXPECT_TRUE(CaughtErrorInfo == 42 && CaughtErrorExtraInfo == 7 &&
271 DummyInfo == 0)
272 << "Activated the wrong Error handler(s)";
273}
274
275// Check that general handlers shadow specific ones.
276TEST(Error, HandlerShadowing) {
277 int CaughtErrorInfo = 0;
278 int DummyInfo = 0;
279 int DummyExtraInfo = 0;
280
281 handleAllErrors(
282 make_error<CustomSubError>(42, 7),
283 [&](const CustomError &CE) { CaughtErrorInfo = CE.getInfo(); },
284 [&](const CustomSubError &SE) {
285 DummyInfo = SE.getInfo();
286 DummyExtraInfo = SE.getExtraInfo();
287 });
288
NAKAMURA Takumib2cef642016-03-24 15:19:22 +0000289 EXPECT_TRUE(CaughtErrorInfo == 42 && DummyInfo == 0 && DummyExtraInfo == 0)
Lang Hames01864a22016-03-18 00:12:37 +0000290 << "General Error handler did not shadow specific handler";
291}
292
293// Test joinErrors.
294TEST(Error, CheckJoinErrors) {
295 int CustomErrorInfo1 = 0;
296 int CustomErrorInfo2 = 0;
297 int CustomErrorExtraInfo = 0;
298 Error E =
299 joinErrors(make_error<CustomError>(7), make_error<CustomSubError>(42, 7));
300
301 handleAllErrors(std::move(E),
302 [&](const CustomSubError &SE) {
303 CustomErrorInfo2 = SE.getInfo();
304 CustomErrorExtraInfo = SE.getExtraInfo();
305 },
306 [&](const CustomError &CE) {
307 // Assert that the CustomError instance above is handled
308 // before the
309 // CustomSubError - joinErrors should preserve error
310 // ordering.
311 EXPECT_EQ(CustomErrorInfo2, 0)
312 << "CustomErrorInfo2 should be 0 here. "
313 "joinErrors failed to preserve ordering.\n";
314 CustomErrorInfo1 = CE.getInfo();
315 });
316
317 EXPECT_TRUE(CustomErrorInfo1 == 7 && CustomErrorInfo2 == 42 &&
318 CustomErrorExtraInfo == 7)
319 << "Failed handling compound Error.";
Lang Hames759b30e2016-06-30 17:43:06 +0000320
321 // Test appending a single item to a list.
322 {
323 int Sum = 0;
324 handleAllErrors(
325 joinErrors(
326 joinErrors(make_error<CustomError>(7),
327 make_error<CustomError>(7)),
328 make_error<CustomError>(7)),
329 [&](const CustomError &CE) {
330 Sum += CE.getInfo();
331 });
332 EXPECT_EQ(Sum, 21) << "Failed to correctly append error to error list.";
333 }
334
335 // Test prepending a single item to a list.
336 {
337 int Sum = 0;
338 handleAllErrors(
339 joinErrors(
340 make_error<CustomError>(7),
341 joinErrors(make_error<CustomError>(7),
342 make_error<CustomError>(7))),
343 [&](const CustomError &CE) {
344 Sum += CE.getInfo();
345 });
346 EXPECT_EQ(Sum, 21) << "Failed to correctly prepend error to error list.";
347 }
348
349 // Test concatenating two error lists.
350 {
351 int Sum = 0;
352 handleAllErrors(
353 joinErrors(
354 joinErrors(
355 make_error<CustomError>(7),
356 make_error<CustomError>(7)),
357 joinErrors(
358 make_error<CustomError>(7),
359 make_error<CustomError>(7))),
360 [&](const CustomError &CE) {
361 Sum += CE.getInfo();
362 });
Hiroshi Inoue0ca79dc2017-07-11 06:04:59 +0000363 EXPECT_EQ(Sum, 28) << "Failed to correctly concatenate error lists.";
Lang Hames759b30e2016-06-30 17:43:06 +0000364 }
Lang Hames01864a22016-03-18 00:12:37 +0000365}
366
367// Test that we can consume success values.
368TEST(Error, ConsumeSuccess) {
Mehdi Aminic1edf562016-11-11 04:29:25 +0000369 Error E = Error::success();
Lang Hames01864a22016-03-18 00:12:37 +0000370 consumeError(std::move(E));
371}
372
373TEST(Error, ConsumeError) {
374 Error E = make_error<CustomError>(7);
375 consumeError(std::move(E));
376}
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000377
378// Test that handleAllUnhandledErrors crashes if an error is not caught.
379// Test runs in debug mode only.
Mehdi Aminicb79c072016-11-30 19:08:41 +0000380#if LLVM_ENABLE_ABI_BREAKING_CHECKS
Lang Hames01864a22016-03-18 00:12:37 +0000381TEST(Error, FailureToHandle) {
382 auto FailToHandle = []() {
383 handleAllErrors(make_error<CustomError>(7), [&](const CustomSubError &SE) {
384 errs() << "This should never be called";
385 exit(1);
386 });
387 };
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000388
Lang Hames7febf2b2017-08-24 05:35:27 +0000389 EXPECT_DEATH(FailToHandle(),
390 "Failure value returned from cantFail wrapped call")
Lang Hames01864a22016-03-18 00:12:37 +0000391 << "Unhandled Error in handleAllErrors call did not cause an "
392 "abort()";
393}
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000394#endif
395
396// Test that handleAllUnhandledErrors crashes if an error is returned from a
397// handler.
398// Test runs in debug mode only.
Mehdi Aminicb79c072016-11-30 19:08:41 +0000399#if LLVM_ENABLE_ABI_BREAKING_CHECKS
Lang Hames01864a22016-03-18 00:12:37 +0000400TEST(Error, FailureFromHandler) {
401 auto ReturnErrorFromHandler = []() {
402 handleAllErrors(make_error<CustomError>(7),
403 [&](std::unique_ptr<CustomSubError> SE) {
404 return Error(std::move(SE));
405 });
406 };
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000407
Lang Hames01864a22016-03-18 00:12:37 +0000408 EXPECT_DEATH(ReturnErrorFromHandler(),
Lang Hames7febf2b2017-08-24 05:35:27 +0000409 "Failure value returned from cantFail wrapped call")
Lang Hames01864a22016-03-18 00:12:37 +0000410 << " Error returned from handler in handleAllErrors call did not "
411 "cause abort()";
412}
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000413#endif
414
Lang Hames01864a22016-03-18 00:12:37 +0000415// Test that we can return values from handleErrors.
416TEST(Error, CatchErrorFromHandler) {
417 int ErrorInfo = 0;
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000418
Lang Hames01864a22016-03-18 00:12:37 +0000419 Error E = handleErrors(
420 make_error<CustomError>(7),
421 [&](std::unique_ptr<CustomError> CE) { return Error(std::move(CE)); });
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000422
Lang Hames01864a22016-03-18 00:12:37 +0000423 handleAllErrors(std::move(E),
424 [&](const CustomError &CE) { ErrorInfo = CE.getInfo(); });
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000425
Lang Hames01864a22016-03-18 00:12:37 +0000426 EXPECT_EQ(ErrorInfo, 7)
427 << "Failed to handle Error returned from handleErrors.";
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000428}
429
Lang Hamesc5e0bbd2016-05-27 01:37:32 +0000430TEST(Error, StringError) {
431 std::string Msg;
432 raw_string_ostream S(Msg);
433 logAllUnhandledErrors(make_error<StringError>("foo" + Twine(42),
Lang Hamesbd8e9542016-05-27 01:54:25 +0000434 inconvertibleErrorCode()),
Lang Hamesc5e0bbd2016-05-27 01:37:32 +0000435 S, "");
436 EXPECT_EQ(S.str(), "foo42\n") << "Unexpected StringError log result";
437
438 auto EC =
439 errorToErrorCode(make_error<StringError>("", errc::invalid_argument));
440 EXPECT_EQ(EC, errc::invalid_argument)
441 << "Failed to convert StringError to error_code.";
442}
443
Lang Hames01864a22016-03-18 00:12:37 +0000444// Test that the ExitOnError utility works as expected.
445TEST(Error, ExitOnError) {
446 ExitOnError ExitOnErr;
447 ExitOnErr.setBanner("Error in tool:");
448 ExitOnErr.setExitCodeMapper([](const Error &E) {
449 if (E.isA<CustomSubError>())
450 return 2;
451 return 1;
452 });
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000453
Lang Hames01864a22016-03-18 00:12:37 +0000454 // Make sure we don't bail on success.
455 ExitOnErr(Error::success());
456 EXPECT_EQ(ExitOnErr(Expected<int>(7)), 7)
457 << "exitOnError returned an invalid value for Expected";
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000458
Lang Hames285639f2016-04-25 19:21:57 +0000459 int A = 7;
460 int &B = ExitOnErr(Expected<int&>(A));
461 EXPECT_EQ(&A, &B) << "ExitOnError failed to propagate reference";
462
Lang Hames01864a22016-03-18 00:12:37 +0000463 // Exit tests.
464 EXPECT_EXIT(ExitOnErr(make_error<CustomError>(7)),
465 ::testing::ExitedWithCode(1), "Error in tool:")
466 << "exitOnError returned an unexpected error result";
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000467
Lang Hames01864a22016-03-18 00:12:37 +0000468 EXPECT_EXIT(ExitOnErr(Expected<int>(make_error<CustomSubError>(0, 0))),
469 ::testing::ExitedWithCode(2), "Error in tool:")
470 << "exitOnError returned an unexpected error result";
471}
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000472
Lang Hamesfd4de912017-02-27 21:09:47 +0000473// Test that the ExitOnError utility works as expected.
474TEST(Error, CantFailSuccess) {
475 cantFail(Error::success());
476
477 int X = cantFail(Expected<int>(42));
478 EXPECT_EQ(X, 42) << "Expected value modified by cantFail";
Lang Hamescd227532017-06-20 22:18:02 +0000479
480 int Dummy = 42;
481 int &Y = cantFail(Expected<int&>(Dummy));
482 EXPECT_EQ(&Dummy, &Y) << "Reference mangled by cantFail";
Lang Hamesfd4de912017-02-27 21:09:47 +0000483}
484
485// Test that cantFail results in a crash if you pass it a failure value.
Stephen Hinescc14a382017-08-25 00:48:21 +0000486#if LLVM_ENABLE_ABI_BREAKING_CHECKS && !defined(NDEBUG)
Lang Hamesfd4de912017-02-27 21:09:47 +0000487TEST(Error, CantFailDeath) {
488 EXPECT_DEATH(
Lang Hames3025e482017-08-29 23:29:09 +0000489 cantFail(make_error<StringError>("foo", inconvertibleErrorCode()),
490 "Cantfail call failed"),
491 "Cantfail call failed")
Lang Hamesfd4de912017-02-27 21:09:47 +0000492 << "cantFail(Error) did not cause an abort for failure value";
493
494 EXPECT_DEATH(
495 {
496 auto IEC = inconvertibleErrorCode();
497 int X = cantFail(Expected<int>(make_error<StringError>("foo", IEC)));
498 (void)X;
499 },
500 "Failure value returned from cantFail wrapped call")
501 << "cantFail(Expected<int>) did not cause an abort for failure value";
502}
503#endif
504
505
Lang Hames580ca232016-04-05 19:57:03 +0000506// Test Checked Expected<T> in success mode.
507TEST(Error, CheckedExpectedInSuccessMode) {
Lang Hames01864a22016-03-18 00:12:37 +0000508 Expected<int> A = 7;
509 EXPECT_TRUE(!!A) << "Expected with non-error value doesn't convert to 'true'";
Lang Hames580ca232016-04-05 19:57:03 +0000510 // Access is safe in second test, since we checked the error in the first.
Lang Hames01864a22016-03-18 00:12:37 +0000511 EXPECT_EQ(*A, 7) << "Incorrect Expected non-error value";
512}
513
Lang Hames285639f2016-04-25 19:21:57 +0000514// Test Expected with reference type.
515TEST(Error, ExpectedWithReferenceType) {
516 int A = 7;
517 Expected<int&> B = A;
518 // 'Check' B.
519 (void)!!B;
520 int &C = *B;
521 EXPECT_EQ(&A, &C) << "Expected failed to propagate reference";
522}
523
Lang Hames580ca232016-04-05 19:57:03 +0000524// Test Unchecked Expected<T> in success mode.
525// We expect this to blow up the same way Error would.
526// Test runs in debug mode only.
Mehdi Aminicb79c072016-11-30 19:08:41 +0000527#if LLVM_ENABLE_ABI_BREAKING_CHECKS
Lang Hames580ca232016-04-05 19:57:03 +0000528TEST(Error, UncheckedExpectedInSuccessModeDestruction) {
529 EXPECT_DEATH({ Expected<int> A = 7; },
530 "Expected<T> must be checked before access or destruction.")
531 << "Unchecekd Expected<T> success value did not cause an abort().";
532}
533#endif
534
535// Test Unchecked Expected<T> in success mode.
536// We expect this to blow up the same way Error would.
537// Test runs in debug mode only.
Mehdi Aminicb79c072016-11-30 19:08:41 +0000538#if LLVM_ENABLE_ABI_BREAKING_CHECKS
Lang Hames580ca232016-04-05 19:57:03 +0000539TEST(Error, UncheckedExpectedInSuccessModeAccess) {
540 EXPECT_DEATH({ Expected<int> A = 7; *A; },
541 "Expected<T> must be checked before access or destruction.")
542 << "Unchecekd Expected<T> success value did not cause an abort().";
543}
544#endif
545
546// Test Unchecked Expected<T> in success mode.
547// We expect this to blow up the same way Error would.
548// Test runs in debug mode only.
Mehdi Aminicb79c072016-11-30 19:08:41 +0000549#if LLVM_ENABLE_ABI_BREAKING_CHECKS
Lang Hames580ca232016-04-05 19:57:03 +0000550TEST(Error, UncheckedExpectedInSuccessModeAssignment) {
551 EXPECT_DEATH({ Expected<int> A = 7; A = 7; },
552 "Expected<T> must be checked before access or destruction.")
553 << "Unchecekd Expected<T> success value did not cause an abort().";
554}
555#endif
556
Lang Hames01864a22016-03-18 00:12:37 +0000557// Test Expected<T> in failure mode.
558TEST(Error, ExpectedInFailureMode) {
559 Expected<int> A = make_error<CustomError>(42);
560 EXPECT_FALSE(!!A) << "Expected with error value doesn't convert to 'false'";
561 Error E = A.takeError();
562 EXPECT_TRUE(E.isA<CustomError>()) << "Incorrect Expected error value";
563 consumeError(std::move(E));
564}
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000565
566// Check that an Expected instance with an error value doesn't allow access to
567// operator*.
568// Test runs in debug mode only.
Mehdi Aminicb79c072016-11-30 19:08:41 +0000569#if LLVM_ENABLE_ABI_BREAKING_CHECKS
Lang Hames01864a22016-03-18 00:12:37 +0000570TEST(Error, AccessExpectedInFailureMode) {
571 Expected<int> A = make_error<CustomError>(42);
Lang Hames580ca232016-04-05 19:57:03 +0000572 EXPECT_DEATH(*A, "Expected<T> must be checked before access or destruction.")
Lang Hames01864a22016-03-18 00:12:37 +0000573 << "Incorrect Expected error value";
574 consumeError(A.takeError());
575}
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000576#endif
577
578// Check that an Expected instance with an error triggers an abort if
579// unhandled.
580// Test runs in debug mode only.
Mehdi Aminicb79c072016-11-30 19:08:41 +0000581#if LLVM_ENABLE_ABI_BREAKING_CHECKS
Lang Hames01864a22016-03-18 00:12:37 +0000582TEST(Error, UnhandledExpectedInFailureMode) {
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000583 EXPECT_DEATH({ Expected<int> A = make_error<CustomError>(42); },
Lang Hames580ca232016-04-05 19:57:03 +0000584 "Expected<T> must be checked before access or destruction.")
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000585 << "Unchecked Expected<T> failure value did not cause an abort()";
Lang Hames01864a22016-03-18 00:12:37 +0000586}
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000587#endif
588
Lang Hames01864a22016-03-18 00:12:37 +0000589// Test covariance of Expected.
590TEST(Error, ExpectedCovariance) {
591 class B {};
592 class D : public B {};
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000593
Lang Hames01864a22016-03-18 00:12:37 +0000594 Expected<B *> A1(Expected<D *>(nullptr));
Lang Hames580ca232016-04-05 19:57:03 +0000595 // Check A1 by converting to bool before assigning to it.
596 (void)!!A1;
Lang Hames01864a22016-03-18 00:12:37 +0000597 A1 = Expected<D *>(nullptr);
Lang Hames580ca232016-04-05 19:57:03 +0000598 // Check A1 again before destruction.
599 (void)!!A1;
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000600
Lang Hames01864a22016-03-18 00:12:37 +0000601 Expected<std::unique_ptr<B>> A2(Expected<std::unique_ptr<D>>(nullptr));
Lang Hames580ca232016-04-05 19:57:03 +0000602 // Check A2 by converting to bool before assigning to it.
603 (void)!!A2;
Lang Hames01864a22016-03-18 00:12:37 +0000604 A2 = Expected<std::unique_ptr<D>>(nullptr);
Lang Hames580ca232016-04-05 19:57:03 +0000605 // Check A2 again before destruction.
606 (void)!!A2;
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000607}
608
Lang Hames5d06c232017-08-28 03:36:46 +0000609// Test that handleExpected just returns success values.
610TEST(Error, HandleExpectedSuccess) {
611 auto ValOrErr =
612 handleExpected(Expected<int>(42),
613 []() { return Expected<int>(43); });
614 EXPECT_TRUE(!!ValOrErr)
615 << "handleExpected should have returned a success value here";
616 EXPECT_EQ(*ValOrErr, 42)
617 << "handleExpected should have returned the original success value here";
618}
619
620enum FooStrategy { Aggressive, Conservative };
621
622static Expected<int> foo(FooStrategy S) {
623 if (S == Aggressive)
624 return make_error<CustomError>(7);
625 return 42;
626}
627
628// Test that handleExpected invokes the error path if errors are not handled.
629TEST(Error, HandleExpectedUnhandledError) {
630 // foo(Aggressive) should return a CustomError which should pass through as
631 // there is no handler for CustomError.
632 auto ValOrErr =
633 handleExpected(
634 foo(Aggressive),
635 []() { return foo(Conservative); });
636
637 EXPECT_FALSE(!!ValOrErr)
638 << "handleExpected should have returned an error here";
639 auto Err = ValOrErr.takeError();
640 EXPECT_TRUE(Err.isA<CustomError>())
641 << "handleExpected should have returned the CustomError generated by "
642 "foo(Aggressive) here";
643 consumeError(std::move(Err));
644}
645
646// Test that handleExpected invokes the fallback path if errors are handled.
647TEST(Error, HandleExpectedHandledError) {
648 // foo(Aggressive) should return a CustomError which should handle triggering
649 // the fallback path.
650 auto ValOrErr =
651 handleExpected(
652 foo(Aggressive),
653 []() { return foo(Conservative); },
654 [](const CustomError&) { /* do nothing */ });
655
656 EXPECT_TRUE(!!ValOrErr)
657 << "handleExpected should have returned a success value here";
658 EXPECT_EQ(*ValOrErr, 42)
659 << "handleExpected returned the wrong success value";
660}
661
Lang Hamesd21a5352016-03-24 02:00:10 +0000662TEST(Error, ErrorCodeConversions) {
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000663 // Round-trip a success value to check that it converts correctly.
664 EXPECT_EQ(errorToErrorCode(errorCodeToError(std::error_code())),
665 std::error_code())
666 << "std::error_code() should round-trip via Error conversions";
667
668 // Round-trip an error value to check that it converts correctly.
669 EXPECT_EQ(errorToErrorCode(errorCodeToError(errc::invalid_argument)),
670 errc::invalid_argument)
671 << "std::error_code error value should round-trip via Error "
672 "conversions";
Lang Hamesd21a5352016-03-24 02:00:10 +0000673
674 // Round-trip a success value through ErrorOr/Expected to check that it
675 // converts correctly.
676 {
677 auto Orig = ErrorOr<int>(42);
678 auto RoundTripped =
679 expectedToErrorOr(errorOrToExpected(ErrorOr<int>(42)));
680 EXPECT_EQ(*Orig, *RoundTripped)
681 << "ErrorOr<T> success value should round-trip via Expected<T> "
682 "conversions.";
683 }
684
685 // Round-trip a failure value through ErrorOr/Expected to check that it
686 // converts correctly.
687 {
688 auto Orig = ErrorOr<int>(errc::invalid_argument);
689 auto RoundTripped =
690 expectedToErrorOr(
691 errorOrToExpected(ErrorOr<int>(errc::invalid_argument)));
692 EXPECT_EQ(Orig.getError(), RoundTripped.getError())
693 << "ErrorOr<T> failure value should round-trip via Expected<T> "
694 "conversions.";
695 }
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000696}
697
Vedant Kumar27370a02016-05-03 23:32:31 +0000698// Test that error messages work.
699TEST(Error, ErrorMessage) {
700 EXPECT_EQ(toString(Error::success()).compare(""), 0);
701
702 Error E1 = make_error<CustomError>(0);
703 EXPECT_EQ(toString(std::move(E1)).compare("CustomError { 0}"), 0);
704
705 Error E2 = make_error<CustomError>(0);
706 handleAllErrors(std::move(E2), [](const CustomError &CE) {
707 EXPECT_EQ(CE.message().compare("CustomError { 0}"), 0);
708 });
709
710 Error E3 = joinErrors(make_error<CustomError>(0), make_error<CustomError>(1));
711 EXPECT_EQ(toString(std::move(E3))
712 .compare("CustomError { 0}\n"
713 "CustomError { 1}"),
714 0);
715}
716
Lang Hamesf7f6d3e2016-03-16 01:02:46 +0000717} // end anon namespace