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