1 //===----- 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"
12 #include "llvm/Support/ErrorHandling.h"
13 #include "gtest/gtest.h"
14 #include <memory>
15 
16 using namespace llvm;
17 
18 namespace {
19 
20 // Custom error class with a default base class and some random 'info' attached.
21 class CustomError : public ErrorInfo<CustomError> {
22 public:
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 
34   std::error_code convertToErrorCode() const override {
35     llvm_unreachable("CustomError doesn't support ECError conversion");
36   }
37 
38   // Used by ErrorInfo::classID.
39   static char ID;
40 
41 protected:
42   // This error is subclassed below, but we can't use inheriting constructors
43   // yet, so we can't propagate the constructors through ErrorInfo. Instead
44   // we have to have a default constructor and have the subclass initialize all
45   // fields.
46   CustomError() : Info(0) {}
47 
48   int Info;
49 };
50 
51 char CustomError::ID = 0;
52 
53 // Custom error class with a custom base class and some additional random
54 // 'info'.
55 class CustomSubError : public ErrorInfo<CustomSubError, CustomError> {
56 public:
57   // Create a sub-error with some info attached.
58   CustomSubError(int Info, int ExtraInfo) : ExtraInfo(ExtraInfo) {
59     this->Info = Info;
60   }
61 
62   // Get the extra info attached to this error.
63   int getExtraInfo() const { return ExtraInfo; }
64 
65   // Log this error to a stream.
66   void log(raw_ostream &OS) const override {
67     OS << "CustomSubError { " << getInfo() << ", " << getExtraInfo() << "}";
68   }
69 
70   std::error_code convertToErrorCode() const override {
71     llvm_unreachable("CustomSubError doesn't support ECError conversion");
72   }
73 
74   // Used by ErrorInfo::classID.
75   static char ID;
76 
77 protected:
78   int ExtraInfo;
79 };
80 
81 char CustomSubError::ID = 0;
82 
83 static Error handleCustomError(const CustomError &CE) { return Error(); }
84 
85 static void handleCustomErrorVoid(const CustomError &CE) {}
86 
87 static Error handleCustomErrorUP(std::unique_ptr<CustomError> CE) {
88   return Error();
89 }
90 
91 static void handleCustomErrorUPVoid(std::unique_ptr<CustomError> CE) {}
92 
93 // Test that success values implicitly convert to false, and don't cause crashes
94 // once they've been implicitly converted.
95 TEST(Error, CheckedSuccess) {
96   Error E;
97   EXPECT_FALSE(E) << "Unexpected error while testing Error 'Success'";
98 }
99 
100 // Test that unchecked succes values cause an abort.
101 #ifndef NDEBUG
102 TEST(Error, UncheckedSuccess) {
103   EXPECT_DEATH({ Error E; }, "Program aborted due to an unhandled Error:")
104       << "Unchecked Error Succes value did not cause abort()";
105 }
106 #endif
107 
108 // ErrorAsOutParameter tester.
109 void errAsOutParamHelper(Error &Err) {
110   ErrorAsOutParameter ErrAsOutParam(Err);
111   // Verify that checked flag is raised - assignment should not crash.
112   Err = Error::success();
113   // Raise the checked bit manually - caller should still have to test the
114   // error.
115   (void)!!Err;
116 }
117 
118 // Test that ErrorAsOutParameter sets the checked flag on construction.
119 TEST(Error, ErrorAsOutParameterChecked) {
120   Error E;
121   errAsOutParamHelper(E);
122   (void)!!E;
123 }
124 
125 // Test that ErrorAsOutParameter clears the checked flag on destruction.
126 #ifndef NDEBUG
127 TEST(Error, ErrorAsOutParameterUnchecked) {
128   EXPECT_DEATH({ Error E; errAsOutParamHelper(E); },
129                "Program aborted due to an unhandled Error:")
130       << "ErrorAsOutParameter did not clear the checked flag on destruction.";
131 }
132 #endif
133 
134 // Check that we abort on unhandled failure cases. (Force conversion to bool
135 // to make sure that we don't accidentally treat checked errors as handled).
136 // Test runs in debug mode only.
137 #ifndef NDEBUG
138 TEST(Error, UncheckedError) {
139   auto DropUnhandledError = []() {
140     Error E = make_error<CustomError>(42);
141     (void)!E;
142   };
143   EXPECT_DEATH(DropUnhandledError(),
144                "Program aborted due to an unhandled Error:")
145       << "Unhandled Error failure value did not cause abort()";
146 }
147 #endif
148 
149 // Check 'Error::isA<T>' method handling.
150 TEST(Error, IsAHandling) {
151   // Check 'isA' handling.
152   Error E = make_error<CustomError>(1);
153   Error F = make_error<CustomSubError>(1, 2);
154   Error G = Error::success();
155 
156   EXPECT_TRUE(E.isA<CustomError>());
157   EXPECT_FALSE(E.isA<CustomSubError>());
158   EXPECT_TRUE(F.isA<CustomError>());
159   EXPECT_TRUE(F.isA<CustomSubError>());
160   EXPECT_FALSE(G.isA<CustomError>());
161 
162   consumeError(std::move(E));
163   consumeError(std::move(F));
164   consumeError(std::move(G));
165 }
166 
167 // Check that we can handle a custom error.
168 TEST(Error, HandleCustomError) {
169   int CaughtErrorInfo = 0;
170   handleAllErrors(make_error<CustomError>(42), [&](const CustomError &CE) {
171     CaughtErrorInfo = CE.getInfo();
172   });
173 
174   EXPECT_TRUE(CaughtErrorInfo == 42) << "Wrong result from CustomError handler";
175 }
176 
177 // Check that handler type deduction also works for handlers
178 // of the following types:
179 // void (const Err&)
180 // Error (const Err&) mutable
181 // void (const Err&) mutable
182 // Error (Err&)
183 // void (Err&)
184 // Error (Err&) mutable
185 // void (Err&) mutable
186 // Error (unique_ptr<Err>)
187 // void (unique_ptr<Err>)
188 // Error (unique_ptr<Err>) mutable
189 // void (unique_ptr<Err>) mutable
190 TEST(Error, HandlerTypeDeduction) {
191 
192   handleAllErrors(make_error<CustomError>(42), [](const CustomError &CE) {});
193 
194   handleAllErrors(
195       make_error<CustomError>(42),
196       [](const CustomError &CE) mutable { return Error::success(); });
197 
198   handleAllErrors(make_error<CustomError>(42),
199                   [](const CustomError &CE) mutable {});
200 
201   handleAllErrors(make_error<CustomError>(42),
202                   [](CustomError &CE) { return Error::success(); });
203 
204   handleAllErrors(make_error<CustomError>(42), [](CustomError &CE) {});
205 
206   handleAllErrors(make_error<CustomError>(42),
207                   [](CustomError &CE) mutable { return Error::success(); });
208 
209   handleAllErrors(make_error<CustomError>(42), [](CustomError &CE) mutable {});
210 
211   handleAllErrors(
212       make_error<CustomError>(42),
213       [](std::unique_ptr<CustomError> CE) { return Error::success(); });
214 
215   handleAllErrors(make_error<CustomError>(42),
216                   [](std::unique_ptr<CustomError> CE) {});
217 
218   handleAllErrors(
219       make_error<CustomError>(42),
220       [](std::unique_ptr<CustomError> CE) mutable { return Error::success(); });
221 
222   handleAllErrors(make_error<CustomError>(42),
223                   [](std::unique_ptr<CustomError> CE) mutable {});
224 
225   // Check that named handlers of type 'Error (const Err&)' work.
226   handleAllErrors(make_error<CustomError>(42), handleCustomError);
227 
228   // Check that named handlers of type 'void (const Err&)' work.
229   handleAllErrors(make_error<CustomError>(42), handleCustomErrorVoid);
230 
231   // Check that named handlers of type 'Error (std::unique_ptr<Err>)' work.
232   handleAllErrors(make_error<CustomError>(42), handleCustomErrorUP);
233 
234   // Check that named handlers of type 'Error (std::unique_ptr<Err>)' work.
235   handleAllErrors(make_error<CustomError>(42), handleCustomErrorUPVoid);
236 }
237 
238 // Test that we can handle errors with custom base classes.
239 TEST(Error, HandleCustomErrorWithCustomBaseClass) {
240   int CaughtErrorInfo = 0;
241   int CaughtErrorExtraInfo = 0;
242   handleAllErrors(make_error<CustomSubError>(42, 7),
243                   [&](const CustomSubError &SE) {
244                     CaughtErrorInfo = SE.getInfo();
245                     CaughtErrorExtraInfo = SE.getExtraInfo();
246                   });
247 
248   EXPECT_TRUE(CaughtErrorInfo == 42 && CaughtErrorExtraInfo == 7)
249       << "Wrong result from CustomSubError handler";
250 }
251 
252 // Check that we trigger only the first handler that applies.
253 TEST(Error, FirstHandlerOnly) {
254   int DummyInfo = 0;
255   int CaughtErrorInfo = 0;
256   int CaughtErrorExtraInfo = 0;
257 
258   handleAllErrors(make_error<CustomSubError>(42, 7),
259                   [&](const CustomSubError &SE) {
260                     CaughtErrorInfo = SE.getInfo();
261                     CaughtErrorExtraInfo = SE.getExtraInfo();
262                   },
263                   [&](const CustomError &CE) { DummyInfo = CE.getInfo(); });
264 
265   EXPECT_TRUE(CaughtErrorInfo == 42 && CaughtErrorExtraInfo == 7 &&
266               DummyInfo == 0)
267       << "Activated the wrong Error handler(s)";
268 }
269 
270 // Check that general handlers shadow specific ones.
271 TEST(Error, HandlerShadowing) {
272   int CaughtErrorInfo = 0;
273   int DummyInfo = 0;
274   int DummyExtraInfo = 0;
275 
276   handleAllErrors(
277       make_error<CustomSubError>(42, 7),
278       [&](const CustomError &CE) { CaughtErrorInfo = CE.getInfo(); },
279       [&](const CustomSubError &SE) {
280         DummyInfo = SE.getInfo();
281         DummyExtraInfo = SE.getExtraInfo();
282       });
283 
284   EXPECT_TRUE(CaughtErrorInfo == 42 && DummyInfo == 0 && DummyExtraInfo == 0)
285       << "General Error handler did not shadow specific handler";
286 }
287 
288 // Test joinErrors.
289 TEST(Error, CheckJoinErrors) {
290   int CustomErrorInfo1 = 0;
291   int CustomErrorInfo2 = 0;
292   int CustomErrorExtraInfo = 0;
293   Error E =
294       joinErrors(make_error<CustomError>(7), make_error<CustomSubError>(42, 7));
295 
296   handleAllErrors(std::move(E),
297                   [&](const CustomSubError &SE) {
298                     CustomErrorInfo2 = SE.getInfo();
299                     CustomErrorExtraInfo = SE.getExtraInfo();
300                   },
301                   [&](const CustomError &CE) {
302                     // Assert that the CustomError instance above is handled
303                     // before the
304                     // CustomSubError - joinErrors should preserve error
305                     // ordering.
306                     EXPECT_EQ(CustomErrorInfo2, 0)
307                         << "CustomErrorInfo2 should be 0 here. "
308                            "joinErrors failed to preserve ordering.\n";
309                     CustomErrorInfo1 = CE.getInfo();
310                   });
311 
312   EXPECT_TRUE(CustomErrorInfo1 == 7 && CustomErrorInfo2 == 42 &&
313               CustomErrorExtraInfo == 7)
314       << "Failed handling compound Error.";
315 }
316 
317 // Test that we can consume success values.
318 TEST(Error, ConsumeSuccess) {
319   Error E;
320   consumeError(std::move(E));
321 }
322 
323 TEST(Error, ConsumeError) {
324   Error E = make_error<CustomError>(7);
325   consumeError(std::move(E));
326 }
327 
328 // Test that handleAllUnhandledErrors crashes if an error is not caught.
329 // Test runs in debug mode only.
330 #ifndef NDEBUG
331 TEST(Error, FailureToHandle) {
332   auto FailToHandle = []() {
333     handleAllErrors(make_error<CustomError>(7), [&](const CustomSubError &SE) {
334       errs() << "This should never be called";
335       exit(1);
336     });
337   };
338 
339   EXPECT_DEATH(FailToHandle(), "Program aborted due to an unhandled Error:")
340       << "Unhandled Error in handleAllErrors call did not cause an "
341          "abort()";
342 }
343 #endif
344 
345 // Test that handleAllUnhandledErrors crashes if an error is returned from a
346 // handler.
347 // Test runs in debug mode only.
348 #ifndef NDEBUG
349 TEST(Error, FailureFromHandler) {
350   auto ReturnErrorFromHandler = []() {
351     handleAllErrors(make_error<CustomError>(7),
352                     [&](std::unique_ptr<CustomSubError> SE) {
353                       return Error(std::move(SE));
354                     });
355   };
356 
357   EXPECT_DEATH(ReturnErrorFromHandler(),
358                "Program aborted due to an unhandled Error:")
359       << " Error returned from handler in handleAllErrors call did not "
360          "cause abort()";
361 }
362 #endif
363 
364 // Test that we can return values from handleErrors.
365 TEST(Error, CatchErrorFromHandler) {
366   int ErrorInfo = 0;
367 
368   Error E = handleErrors(
369       make_error<CustomError>(7),
370       [&](std::unique_ptr<CustomError> CE) { return Error(std::move(CE)); });
371 
372   handleAllErrors(std::move(E),
373                   [&](const CustomError &CE) { ErrorInfo = CE.getInfo(); });
374 
375   EXPECT_EQ(ErrorInfo, 7)
376       << "Failed to handle Error returned from handleErrors.";
377 }
378 
379 // Test that the ExitOnError utility works as expected.
380 TEST(Error, ExitOnError) {
381   ExitOnError ExitOnErr;
382   ExitOnErr.setBanner("Error in tool:");
383   ExitOnErr.setExitCodeMapper([](const Error &E) {
384     if (E.isA<CustomSubError>())
385       return 2;
386     return 1;
387   });
388 
389   // Make sure we don't bail on success.
390   ExitOnErr(Error::success());
391   EXPECT_EQ(ExitOnErr(Expected<int>(7)), 7)
392       << "exitOnError returned an invalid value for Expected";
393 
394   // Exit tests.
395   EXPECT_EXIT(ExitOnErr(make_error<CustomError>(7)),
396               ::testing::ExitedWithCode(1), "Error in tool:")
397       << "exitOnError returned an unexpected error result";
398 
399   EXPECT_EXIT(ExitOnErr(Expected<int>(make_error<CustomSubError>(0, 0))),
400               ::testing::ExitedWithCode(2), "Error in tool:")
401       << "exitOnError returned an unexpected error result";
402 }
403 
404 // Test Checked Expected<T> in success mode.
405 TEST(Error, CheckedExpectedInSuccessMode) {
406   Expected<int> A = 7;
407   EXPECT_TRUE(!!A) << "Expected with non-error value doesn't convert to 'true'";
408   // Access is safe in second test, since we checked the error in the first.
409   EXPECT_EQ(*A, 7) << "Incorrect Expected non-error value";
410 }
411 
412 // Test Unchecked Expected<T> in success mode.
413 // We expect this to blow up the same way Error would.
414 // Test runs in debug mode only.
415 #ifndef NDEBUG
416 TEST(Error, UncheckedExpectedInSuccessModeDestruction) {
417   EXPECT_DEATH({ Expected<int> A = 7; },
418                "Expected<T> must be checked before access or destruction.")
419     << "Unchecekd Expected<T> success value did not cause an abort().";
420 }
421 #endif
422 
423 // Test Unchecked Expected<T> in success mode.
424 // We expect this to blow up the same way Error would.
425 // Test runs in debug mode only.
426 #ifndef NDEBUG
427 TEST(Error, UncheckedExpectedInSuccessModeAccess) {
428   EXPECT_DEATH({ Expected<int> A = 7; *A; },
429                "Expected<T> must be checked before access or destruction.")
430     << "Unchecekd Expected<T> success value did not cause an abort().";
431 }
432 #endif
433 
434 // Test Unchecked Expected<T> in success mode.
435 // We expect this to blow up the same way Error would.
436 // Test runs in debug mode only.
437 #ifndef NDEBUG
438 TEST(Error, UncheckedExpectedInSuccessModeAssignment) {
439   EXPECT_DEATH({ Expected<int> A = 7; A = 7; },
440                "Expected<T> must be checked before access or destruction.")
441     << "Unchecekd Expected<T> success value did not cause an abort().";
442 }
443 #endif
444 
445 // Test Expected<T> in failure mode.
446 TEST(Error, ExpectedInFailureMode) {
447   Expected<int> A = make_error<CustomError>(42);
448   EXPECT_FALSE(!!A) << "Expected with error value doesn't convert to 'false'";
449   Error E = A.takeError();
450   EXPECT_TRUE(E.isA<CustomError>()) << "Incorrect Expected error value";
451   consumeError(std::move(E));
452 }
453 
454 // Check that an Expected instance with an error value doesn't allow access to
455 // operator*.
456 // Test runs in debug mode only.
457 #ifndef NDEBUG
458 TEST(Error, AccessExpectedInFailureMode) {
459   Expected<int> A = make_error<CustomError>(42);
460   EXPECT_DEATH(*A, "Expected<T> must be checked before access or destruction.")
461       << "Incorrect Expected error value";
462   consumeError(A.takeError());
463 }
464 #endif
465 
466 // Check that an Expected instance with an error triggers an abort if
467 // unhandled.
468 // Test runs in debug mode only.
469 #ifndef NDEBUG
470 TEST(Error, UnhandledExpectedInFailureMode) {
471   EXPECT_DEATH({ Expected<int> A = make_error<CustomError>(42); },
472                "Expected<T> must be checked before access or destruction.")
473       << "Unchecked Expected<T> failure value did not cause an abort()";
474 }
475 #endif
476 
477 // Test covariance of Expected.
478 TEST(Error, ExpectedCovariance) {
479   class B {};
480   class D : public B {};
481 
482   Expected<B *> A1(Expected<D *>(nullptr));
483   // Check A1 by converting to bool before assigning to it.
484   (void)!!A1;
485   A1 = Expected<D *>(nullptr);
486   // Check A1 again before destruction.
487   (void)!!A1;
488 
489   Expected<std::unique_ptr<B>> A2(Expected<std::unique_ptr<D>>(nullptr));
490   // Check A2 by converting to bool before assigning to it.
491   (void)!!A2;
492   A2 = Expected<std::unique_ptr<D>>(nullptr);
493   // Check A2 again before destruction.
494   (void)!!A2;
495 }
496 
497 TEST(Error, ErrorCodeConversions) {
498   // Round-trip a success value to check that it converts correctly.
499   EXPECT_EQ(errorToErrorCode(errorCodeToError(std::error_code())),
500             std::error_code())
501       << "std::error_code() should round-trip via Error conversions";
502 
503   // Round-trip an error value to check that it converts correctly.
504   EXPECT_EQ(errorToErrorCode(errorCodeToError(errc::invalid_argument)),
505             errc::invalid_argument)
506       << "std::error_code error value should round-trip via Error "
507          "conversions";
508 
509   // Round-trip a success value through ErrorOr/Expected to check that it
510   // converts correctly.
511   {
512     auto Orig = ErrorOr<int>(42);
513     auto RoundTripped =
514       expectedToErrorOr(errorOrToExpected(ErrorOr<int>(42)));
515     EXPECT_EQ(*Orig, *RoundTripped)
516       << "ErrorOr<T> success value should round-trip via Expected<T> "
517          "conversions.";
518   }
519 
520   // Round-trip a failure value through ErrorOr/Expected to check that it
521   // converts correctly.
522   {
523     auto Orig = ErrorOr<int>(errc::invalid_argument);
524     auto RoundTripped =
525       expectedToErrorOr(
526           errorOrToExpected(ErrorOr<int>(errc::invalid_argument)));
527     EXPECT_EQ(Orig.getError(), RoundTripped.getError())
528       << "ErrorOr<T> failure value should round-trip via Expected<T> "
529          "conversions.";
530   }
531 }
532 
533 } // end anon namespace
534