brintos

brintos / llvm-project-archived public Read only

0
0
Text · 40.1 KiB · 00c562e Raw
1201 lines · cpp
1//===----- unittests/ErrorTest.cpp - Error.h tests ------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/Support/Error.h"10#include "llvm-c/Error.h"11 12#include "llvm/ADT/Twine.h"13#include "llvm/Support/Errc.h"14#include "llvm/Support/ErrorHandling.h"15#include "llvm/Testing/Support/Error.h"16#include "gmock/gmock.h"17#include "gtest/gtest-spi.h"18#include "gtest/gtest.h"19#include <memory>20 21using namespace llvm;22 23namespace {24 25// Custom error class with a default base class and some random 'info' attached.26class CustomError : public ErrorInfo<CustomError> {27public:28  // Create an error with some info attached.29  CustomError(int Info) : Info(Info) {}30 31  // Get the info attached to this error.32  int getInfo() const { return Info; }33 34  // Log this error to a stream.35  void log(raw_ostream &OS) const override {36    OS << "CustomError {" << getInfo() << "}";37  }38 39  std::error_code convertToErrorCode() const override {40    llvm_unreachable("CustomError doesn't support ECError conversion");41  }42 43  // Used by ErrorInfo::classID.44  static char ID;45 46protected:47  // This error is subclassed below, but we can't use inheriting constructors48  // yet, so we can't propagate the constructors through ErrorInfo. Instead49  // we have to have a default constructor and have the subclass initialize all50  // fields.51  CustomError() : Info(0) {}52 53  int Info;54};55 56char CustomError::ID = 0;57 58// Custom error class with a custom base class and some additional random59// 'info'.60class CustomSubError : public ErrorInfo<CustomSubError, CustomError> {61public:62  // Create a sub-error with some info attached.63  CustomSubError(int Info, int ExtraInfo) : ExtraInfo(ExtraInfo) {64    this->Info = Info;65  }66 67  // Get the extra info attached to this error.68  int getExtraInfo() const { return ExtraInfo; }69 70  // Log this error to a stream.71  void log(raw_ostream &OS) const override {72    OS << "CustomSubError { " << getInfo() << ", " << getExtraInfo() << "}";73  }74 75  std::error_code convertToErrorCode() const override {76    llvm_unreachable("CustomSubError doesn't support ECError conversion");77  }78 79  // Used by ErrorInfo::classID.80  static char ID;81 82protected:83  int ExtraInfo;84};85 86char CustomSubError::ID = 0;87 88static Error handleCustomError(const CustomError &CE) {89  return Error::success();90}91 92static void handleCustomErrorVoid(const CustomError &CE) {}93 94static Error handleCustomErrorUP(std::unique_ptr<CustomError> CE) {95  return Error::success();96}97 98static void handleCustomErrorUPVoid(std::unique_ptr<CustomError> CE) {}99 100// Test that success values implicitly convert to false, and don't cause crashes101// once they've been implicitly converted.102TEST(Error, CheckedSuccess) {103  Error E = Error::success();104  EXPECT_FALSE(E) << "Unexpected error while testing Error 'Success'";105}106 107// Test that unchecked success values cause an abort.108#if LLVM_ENABLE_ABI_BREAKING_CHECKS109TEST(Error, UncheckedSuccess) {110  EXPECT_DEATH({ Error E = Error::success(); },111               "Program aborted due to an unhandled Error:")112      << "Unchecked Error Succes value did not cause abort()";113}114#endif115 116// ErrorAsOutParameter tester.117void errAsOutParamHelper(Error &Err) {118  ErrorAsOutParameter ErrAsOutParam(&Err);119  // Verify that checked flag is raised - assignment should not crash.120  Err = Error::success();121  // Raise the checked bit manually - caller should still have to test the122  // error.123  (void)!!Err;124}125 126// Test that ErrorAsOutParameter sets the checked flag on construction.127TEST(Error, ErrorAsOutParameterChecked) {128  Error E = Error::success();129  errAsOutParamHelper(E);130  (void)!!E;131}132 133// Test that ErrorAsOutParameter clears the checked flag on destruction.134#if LLVM_ENABLE_ABI_BREAKING_CHECKS135TEST(Error, ErrorAsOutParameterUnchecked) {136  EXPECT_DEATH({ Error E = Error::success(); errAsOutParamHelper(E); },137               "Program aborted due to an unhandled Error:")138      << "ErrorAsOutParameter did not clear the checked flag on destruction.";139}140#endif141 142// Check that we abort on unhandled failure cases. (Force conversion to bool143// to make sure that we don't accidentally treat checked errors as handled).144// Test runs in debug mode only.145#if LLVM_ENABLE_ABI_BREAKING_CHECKS146TEST(Error, UncheckedError) {147  auto DropUnhandledError = []() {148    Error E = make_error<CustomError>(42);149    (void)!E;150  };151  EXPECT_DEATH(DropUnhandledError(),152               "Program aborted due to an unhandled Error:")153      << "Unhandled Error failure value did not cause abort()";154}155#endif156 157// Check 'Error::isA<T>' method handling.158TEST(Error, IsAHandling) {159  // Check 'isA' handling.160  Error E = make_error<CustomError>(1);161  Error F = make_error<CustomSubError>(1, 2);162  Error G = Error::success();163 164  EXPECT_TRUE(E.isA<CustomError>());165  EXPECT_FALSE(E.isA<CustomSubError>());166  EXPECT_TRUE(F.isA<CustomError>());167  EXPECT_TRUE(F.isA<CustomSubError>());168  EXPECT_FALSE(G.isA<CustomError>());169 170  consumeError(std::move(E));171  consumeError(std::move(F));172  consumeError(std::move(G));173}174 175// Check that we can handle a custom error.176TEST(Error, HandleCustomError) {177  int CaughtErrorInfo = 0;178  handleAllErrors(make_error<CustomError>(42), [&](const CustomError &CE) {179    CaughtErrorInfo = CE.getInfo();180  });181 182  EXPECT_EQ(CaughtErrorInfo, 42) << "Wrong result from CustomError handler";183}184 185// Check that handler type deduction also works for handlers186// of the following types:187// void (const Err&)188// Error (const Err&) mutable189// void (const Err&) mutable190// Error (Err&)191// void (Err&)192// Error (Err&) mutable193// void (Err&) mutable194// Error (unique_ptr<Err>)195// void (unique_ptr<Err>)196// Error (unique_ptr<Err>) mutable197// void (unique_ptr<Err>) mutable198TEST(Error, HandlerTypeDeduction) {199 200  handleAllErrors(make_error<CustomError>(42), [](const CustomError &CE) {});201 202  handleAllErrors(203      make_error<CustomError>(42),204      [](const CustomError &CE) mutable  -> Error { return Error::success(); });205 206  handleAllErrors(make_error<CustomError>(42),207                  [](const CustomError &CE) mutable {});208 209  handleAllErrors(make_error<CustomError>(42),210                  [](CustomError &CE) -> Error { return Error::success(); });211 212  handleAllErrors(make_error<CustomError>(42), [](CustomError &CE) {});213 214  handleAllErrors(make_error<CustomError>(42),215                  [](CustomError &CE) mutable -> Error { return Error::success(); });216 217  handleAllErrors(make_error<CustomError>(42), [](CustomError &CE) mutable {});218 219  handleAllErrors(220      make_error<CustomError>(42),221      [](std::unique_ptr<CustomError> CE) -> Error { return Error::success(); });222 223  handleAllErrors(make_error<CustomError>(42),224                  [](std::unique_ptr<CustomError> CE) {});225 226  handleAllErrors(227      make_error<CustomError>(42),228      [](std::unique_ptr<CustomError> CE) mutable -> Error { return Error::success(); });229 230  handleAllErrors(make_error<CustomError>(42),231                  [](std::unique_ptr<CustomError> CE) mutable {});232 233  // Check that named handlers of type 'Error (const Err&)' work.234  handleAllErrors(make_error<CustomError>(42), handleCustomError);235 236  // Check that named handlers of type 'void (const Err&)' work.237  handleAllErrors(make_error<CustomError>(42), handleCustomErrorVoid);238 239  // Check that named handlers of type 'Error (std::unique_ptr<Err>)' work.240  handleAllErrors(make_error<CustomError>(42), handleCustomErrorUP);241 242  // Check that named handlers of type 'Error (std::unique_ptr<Err>)' work.243  handleAllErrors(make_error<CustomError>(42), handleCustomErrorUPVoid);244}245 246// Test that we can handle errors with custom base classes.247TEST(Error, HandleCustomErrorWithCustomBaseClass) {248  int CaughtErrorInfo = 0;249  int CaughtErrorExtraInfo = 0;250  handleAllErrors(make_error<CustomSubError>(42, 7),251                  [&](const CustomSubError &SE) {252                    CaughtErrorInfo = SE.getInfo();253                    CaughtErrorExtraInfo = SE.getExtraInfo();254                  });255 256  EXPECT_EQ(CaughtErrorInfo, 42) << "Wrong result from CustomSubError handler";257  EXPECT_EQ(CaughtErrorExtraInfo, 7)258      << "Wrong result from CustomSubError handler";259}260 261// Check that we trigger only the first handler that applies.262TEST(Error, FirstHandlerOnly) {263  int DummyInfo = 0;264  int CaughtErrorInfo = 0;265  int CaughtErrorExtraInfo = 0;266 267  handleAllErrors(make_error<CustomSubError>(42, 7),268                  [&](const CustomSubError &SE) {269                    CaughtErrorInfo = SE.getInfo();270                    CaughtErrorExtraInfo = SE.getExtraInfo();271                  },272                  [&](const CustomError &CE) { DummyInfo = CE.getInfo(); });273 274  EXPECT_EQ(CaughtErrorInfo, 42) << "Activated the wrong Error handler(s)";275  EXPECT_EQ(CaughtErrorExtraInfo, 7) << "Activated the wrong Error handler(s)";276  EXPECT_EQ(DummyInfo, 0) << "Activated the wrong Error handler(s)";277}278 279// Check that general handlers shadow specific ones.280TEST(Error, HandlerShadowing) {281  int CaughtErrorInfo = 0;282  int DummyInfo = 0;283  int DummyExtraInfo = 0;284 285  handleAllErrors(286      make_error<CustomSubError>(42, 7),287      [&](const CustomError &CE) { CaughtErrorInfo = CE.getInfo(); },288      [&](const CustomSubError &SE) {289        DummyInfo = SE.getInfo();290        DummyExtraInfo = SE.getExtraInfo();291      });292 293  EXPECT_EQ(CaughtErrorInfo, 42)294      << "General Error handler did not shadow specific handler";295  EXPECT_EQ(DummyInfo, 0)296      << "General Error handler did not shadow specific handler";297  EXPECT_EQ(DummyExtraInfo, 0)298      << "General Error handler did not shadow specific handler";299}300 301// Test joinErrors.302TEST(Error, CheckJoinErrors) {303  int CustomErrorInfo1 = 0;304  int CustomErrorInfo2 = 0;305  int CustomErrorExtraInfo = 0;306  Error E =307      joinErrors(make_error<CustomError>(7), make_error<CustomSubError>(42, 7));308 309  handleAllErrors(std::move(E),310                  [&](const CustomSubError &SE) {311                    CustomErrorInfo2 = SE.getInfo();312                    CustomErrorExtraInfo = SE.getExtraInfo();313                  },314                  [&](const CustomError &CE) {315                    // Assert that the CustomError instance above is handled316                    // before the317                    // CustomSubError - joinErrors should preserve error318                    // ordering.319                    EXPECT_EQ(CustomErrorInfo2, 0)320                        << "CustomErrorInfo2 should be 0 here. "321                           "joinErrors failed to preserve ordering.\n";322                    CustomErrorInfo1 = CE.getInfo();323                  });324 325  EXPECT_EQ(CustomErrorInfo1, 7) << "Failed handling compound Error.";326  EXPECT_EQ(CustomErrorInfo2, 42) << "Failed handling compound Error.";327  EXPECT_EQ(CustomErrorExtraInfo, 7) << "Failed handling compound Error.";328 329  // Test appending a single item to a list.330  {331    int Sum = 0;332    handleAllErrors(333        joinErrors(334            joinErrors(make_error<CustomError>(7),335                       make_error<CustomError>(7)),336            make_error<CustomError>(7)),337        [&](const CustomError &CE) {338          Sum += CE.getInfo();339        });340    EXPECT_EQ(Sum, 21) << "Failed to correctly append error to error list.";341  }342 343  // Test prepending a single item to a list.344  {345    int Sum = 0;346    handleAllErrors(347        joinErrors(348            make_error<CustomError>(7),349            joinErrors(make_error<CustomError>(7),350                       make_error<CustomError>(7))),351        [&](const CustomError &CE) {352          Sum += CE.getInfo();353        });354    EXPECT_EQ(Sum, 21) << "Failed to correctly prepend error to error list.";355  }356 357  // Test concatenating two error lists.358  {359    int Sum = 0;360    handleAllErrors(361        joinErrors(362            joinErrors(363                make_error<CustomError>(7),364                make_error<CustomError>(7)),365            joinErrors(366                make_error<CustomError>(7),367                make_error<CustomError>(7))),368        [&](const CustomError &CE) {369          Sum += CE.getInfo();370        });371    EXPECT_EQ(Sum, 28) << "Failed to correctly concatenate error lists.";372  }373}374 375// Test that we can consume success values.376TEST(Error, ConsumeSuccess) {377  Error E = Error::success();378  consumeError(std::move(E));379}380 381TEST(Error, ConsumeError) {382  Error E = make_error<CustomError>(7);383  consumeError(std::move(E));384}385 386// Test that handleAllUnhandledErrors crashes if an error is not caught.387// Test runs in debug mode only.388#if LLVM_ENABLE_ABI_BREAKING_CHECKS389TEST(Error, FailureToHandle) {390  auto FailToHandle = []() {391    handleAllErrors(make_error<CustomError>(7), [&](const CustomSubError &SE) {392      errs() << "This should never be called";393      exit(1);394    });395  };396 397  EXPECT_DEATH(FailToHandle(),398               "Failure value returned from cantFail wrapped call\n"399               "CustomError \\{7\\}")400      << "Unhandled Error in handleAllErrors call did not cause an "401         "abort()";402}403#endif404 405// Test that handleAllUnhandledErrors crashes if an error is returned from a406// handler.407// Test runs in debug mode only.408#if LLVM_ENABLE_ABI_BREAKING_CHECKS409TEST(Error, FailureFromHandler) {410  auto ReturnErrorFromHandler = []() {411    handleAllErrors(make_error<CustomError>(7),412                    [&](std::unique_ptr<CustomSubError> SE) {413                      return Error(std::move(SE));414                    });415  };416 417  EXPECT_DEATH(ReturnErrorFromHandler(),418               "Failure value returned from cantFail wrapped call\n"419               "CustomError \\{7\\}")420      << " Error returned from handler in handleAllErrors call did not "421         "cause abort()";422}423#endif424 425// Test that we can return values from handleErrors.426TEST(Error, CatchErrorFromHandler) {427  int ErrorInfo = 0;428 429  Error E = handleErrors(430      make_error<CustomError>(7),431      [&](std::unique_ptr<CustomError> CE) { return Error(std::move(CE)); });432 433  handleAllErrors(std::move(E),434                  [&](const CustomError &CE) { ErrorInfo = CE.getInfo(); });435 436  EXPECT_EQ(ErrorInfo, 7)437      << "Failed to handle Error returned from handleErrors.";438}439 440TEST(Error, StringError) {441  std::string Msg;442  raw_string_ostream S(Msg);443  logAllUnhandledErrors(444      make_error<StringError>("foo" + Twine(42), inconvertibleErrorCode()), S);445  EXPECT_EQ(Msg, "foo42\n") << "Unexpected StringError log result";446 447  auto EC =448    errorToErrorCode(make_error<StringError>("", errc::invalid_argument));449  EXPECT_EQ(EC, errc::invalid_argument)450    << "Failed to convert StringError to error_code.";451}452 453TEST(Error, createStringError) {454  static const char *Bar = "bar";455  static const std::error_code EC = errc::invalid_argument;456  std::string Msg;457  raw_string_ostream S(Msg);458  logAllUnhandledErrors(createStringError(EC, "foo%s%d0x%" PRIx8, Bar, 1, 0xff),459                        S);460  EXPECT_EQ(Msg, "foobar10xff\n")461      << "Unexpected createStringError() log result";462 463  Msg.clear();464  logAllUnhandledErrors(createStringError(EC, Bar), S);465  EXPECT_EQ(Msg, "bar\n")466      << "Unexpected createStringError() (overloaded) log result";467 468  Msg.clear();469  auto Res = errorToErrorCode(createStringError(EC, "foo%s", Bar));470  EXPECT_EQ(Res, EC)471    << "Failed to convert createStringError() result to error_code.";472}473 474// Test that the ExitOnError utility works as expected.475TEST(ErrorDeathTest, ExitOnError) {476  ExitOnError ExitOnErr;477  ExitOnErr.setBanner("Error in tool:");478  ExitOnErr.setExitCodeMapper([](const Error &E) {479    if (E.isA<CustomSubError>())480      return 2;481    return 1;482  });483 484  // Make sure we don't bail on success.485  ExitOnErr(Error::success());486  EXPECT_EQ(ExitOnErr(Expected<int>(7)), 7)487      << "exitOnError returned an invalid value for Expected";488 489  int A = 7;490  int &B = ExitOnErr(Expected<int&>(A));491  EXPECT_EQ(&A, &B) << "ExitOnError failed to propagate reference";492 493  // Exit tests.494  EXPECT_EXIT(ExitOnErr(make_error<CustomError>(7)),495              ::testing::ExitedWithCode(1), "Error in tool:")496      << "exitOnError returned an unexpected error result";497 498  EXPECT_EXIT(ExitOnErr(Expected<int>(make_error<CustomSubError>(0, 0))),499              ::testing::ExitedWithCode(2), "Error in tool:")500      << "exitOnError returned an unexpected error result";501}502 503// Test that the ExitOnError utility works as expected.504TEST(Error, CantFailSuccess) {505  cantFail(Error::success());506 507  int X = cantFail(Expected<int>(42));508  EXPECT_EQ(X, 42) << "Expected value modified by cantFail";509 510  int Dummy = 42;511  int &Y = cantFail(Expected<int&>(Dummy));512  EXPECT_EQ(&Dummy, &Y) << "Reference mangled by cantFail";513}514 515// Test that cantFail results in a crash if you pass it a failure value.516#if LLVM_ENABLE_ABI_BREAKING_CHECKS && !defined(NDEBUG)517TEST(Error, CantFailDeath) {518  EXPECT_DEATH(cantFail(make_error<StringError>("Original error message",519                                                inconvertibleErrorCode()),520                        "Cantfail call failed"),521               "Cantfail call failed\n"522               "Original error message")523      << "cantFail(Error) did not cause an abort for failure value";524 525  EXPECT_DEATH(526      {527        auto IEC = inconvertibleErrorCode();528        int X = cantFail(Expected<int>(make_error<StringError>("foo", IEC)));529        (void)X;530      },531      "Failure value returned from cantFail wrapped call")532    << "cantFail(Expected<int>) did not cause an abort for failure value";533}534#endif535 536 537// Test Checked Expected<T> in success mode.538TEST(Error, CheckedExpectedInSuccessMode) {539  Expected<int> A = 7;540  EXPECT_TRUE(!!A) << "Expected with non-error value doesn't convert to 'true'";541  // Access is safe in second test, since we checked the error in the first.542  EXPECT_EQ(*A, 7) << "Incorrect Expected non-error value";543}544 545// Test Expected with reference type.546TEST(Error, ExpectedWithReferenceType) {547  int A = 7;548  Expected<int&> B = A;549  // 'Check' B.550  (void)!!B;551  int &C = *B;552  EXPECT_EQ(&A, &C) << "Expected failed to propagate reference";553}554 555// Test Unchecked Expected<T> in success mode.556// We expect this to blow up the same way Error would.557// Test runs in debug mode only.558#if LLVM_ENABLE_ABI_BREAKING_CHECKS559TEST(Error, UncheckedExpectedInSuccessModeDestruction) {560  EXPECT_DEATH({ Expected<int> A = 7; },561               "Expected<T> must be checked before access or destruction.")562      << "Unchecked Expected<T> success value did not cause an abort().";563}564#endif565 566// Test Unchecked Expected<T> in success mode.567// We expect this to blow up the same way Error would.568// Test runs in debug mode only.569#if LLVM_ENABLE_ABI_BREAKING_CHECKS570TEST(Error, UncheckedExpectedInSuccessModeAccess) {571  EXPECT_DEATH(572      {573        const Expected<int> A = 7;574        *A;575      },576      "Expected<T> must be checked before access or destruction.")577      << "Unchecked Expected<T> success value did not cause an abort().";578}579#endif580 581// Test Unchecked Expected<T> in success mode.582// We expect this to blow up the same way Error would.583// Test runs in debug mode only.584#if LLVM_ENABLE_ABI_BREAKING_CHECKS585TEST(Error, UncheckedExpectedInSuccessModeAssignment) {586  EXPECT_DEATH(587      {588        Expected<int> A = 7;589        A = 7;590      },591      "Expected<T> must be checked before access or destruction.")592      << "Unchecked Expected<T> success value did not cause an abort().";593}594#endif595 596// Test Expected<T> in failure mode.597TEST(Error, ExpectedInFailureMode) {598  Expected<int> A = make_error<CustomError>(42);599  EXPECT_FALSE(!!A) << "Expected with error value doesn't convert to 'false'";600  Error E = A.takeError();601  EXPECT_TRUE(E.isA<CustomError>()) << "Incorrect Expected error value";602  consumeError(std::move(E));603}604 605// Check that an Expected instance with an error value doesn't allow access to606// operator*.607// Test runs in debug mode only.608#if LLVM_ENABLE_ABI_BREAKING_CHECKS609TEST(Error, AccessExpectedInFailureMode) {610  Expected<int> A = make_error<CustomError>(42);611  EXPECT_DEATH(*A, "Expected<T> must be checked before access or destruction.")612      << "Incorrect Expected error value";613  consumeError(A.takeError());614}615#endif616 617// Check that an Expected instance with an error triggers an abort if618// unhandled.619// Test runs in debug mode only.620#if LLVM_ENABLE_ABI_BREAKING_CHECKS621TEST(Error, UnhandledExpectedInFailureMode) {622  EXPECT_DEATH({ Expected<int> A = make_error<CustomError>(42); },623               "Expected<T> must be checked before access or destruction.")624      << "Unchecked Expected<T> failure value did not cause an abort()";625}626#endif627 628// Test covariance of Expected.629TEST(Error, ExpectedCovariance) {630  class B {};631  class D : public B {};632 633  Expected<B *> A1(Expected<D *>(nullptr));634  // Check A1 by converting to bool before assigning to it.635  (void)!!A1;636  A1 = Expected<D *>(nullptr);637  // Check A1 again before destruction.638  (void)!!A1;639 640  Expected<std::unique_ptr<B>> A2(Expected<std::unique_ptr<D>>(nullptr));641  // Check A2 by converting to bool before assigning to it.642  (void)!!A2;643  A2 = Expected<std::unique_ptr<D>>(nullptr);644  // Check A2 again before destruction.645  (void)!!A2;646}647 648// Test that handleExpected just returns success values.649TEST(Error, HandleExpectedSuccess) {650  auto ValOrErr =651    handleExpected(Expected<int>(42),652                   []() { return Expected<int>(43); });653  EXPECT_TRUE(!!ValOrErr)654    << "handleExpected should have returned a success value here";655  EXPECT_EQ(*ValOrErr, 42)656    << "handleExpected should have returned the original success value here";657}658 659enum FooStrategy { Aggressive, Conservative };660 661static Expected<int> foo(FooStrategy S) {662  if (S == Aggressive)663    return make_error<CustomError>(7);664  return 42;665}666 667// Test that handleExpected invokes the error path if errors are not handled.668TEST(Error, HandleExpectedUnhandledError) {669  // foo(Aggressive) should return a CustomError which should pass through as670  // there is no handler for CustomError.671  auto ValOrErr =672    handleExpected(673      foo(Aggressive),674      []() { return foo(Conservative); });675 676  EXPECT_FALSE(!!ValOrErr)677    << "handleExpected should have returned an error here";678  auto Err = ValOrErr.takeError();679  EXPECT_TRUE(Err.isA<CustomError>())680    << "handleExpected should have returned the CustomError generated by "681    "foo(Aggressive) here";682  consumeError(std::move(Err));683}684 685// Test that handleExpected invokes the fallback path if errors are handled.686TEST(Error, HandleExpectedHandledError) {687  // foo(Aggressive) should return a CustomError which should handle triggering688  // the fallback path.689  auto ValOrErr =690    handleExpected(691      foo(Aggressive),692      []() { return foo(Conservative); },693      [](const CustomError&) { /* do nothing */ });694 695  EXPECT_TRUE(!!ValOrErr)696    << "handleExpected should have returned a success value here";697  EXPECT_EQ(*ValOrErr, 42)698    << "handleExpected returned the wrong success value";699}700 701TEST(Error, ErrorCodeConversions) {702  // Round-trip a success value to check that it converts correctly.703  EXPECT_EQ(errorToErrorCode(errorCodeToError(std::error_code())),704            std::error_code())705      << "std::error_code() should round-trip via Error conversions";706 707  // Round-trip an error value to check that it converts correctly.708  EXPECT_EQ(errorToErrorCode(errorCodeToError(errc::invalid_argument)),709            errc::invalid_argument)710      << "std::error_code error value should round-trip via Error "711         "conversions";712 713  // Round-trip a success value through ErrorOr/Expected to check that it714  // converts correctly.715  {716    auto Orig = ErrorOr<int>(42);717    auto RoundTripped =718      expectedToErrorOr(errorOrToExpected(ErrorOr<int>(42)));719    EXPECT_EQ(*Orig, *RoundTripped)720      << "ErrorOr<T> success value should round-trip via Expected<T> "721         "conversions.";722  }723 724  // Round-trip a failure value through ErrorOr/Expected to check that it725  // converts correctly.726  {727    auto Orig = ErrorOr<int>(errc::invalid_argument);728    auto RoundTripped =729      expectedToErrorOr(730          errorOrToExpected(ErrorOr<int>(errc::invalid_argument)));731    EXPECT_EQ(Orig.getError(), RoundTripped.getError())732      << "ErrorOr<T> failure value should round-trip via Expected<T> "733         "conversions.";734  }735}736 737// Test that error messages work.738TEST(Error, ErrorMessage) {739  EXPECT_EQ(toString(Error::success()), "");740 741  Error E0 = Error::success();742  EXPECT_EQ(toStringWithoutConsuming(E0), "");743  EXPECT_EQ(toString(std::move(E0)), "");744 745  Error E1 = make_error<CustomError>(0);746  EXPECT_EQ(toStringWithoutConsuming(E1), "CustomError {0}");747  EXPECT_EQ(toString(std::move(E1)), "CustomError {0}");748 749  Error E2 = make_error<CustomError>(0);750  visitErrors(E2, [](const ErrorInfoBase &EI) {751    EXPECT_EQ(EI.message(), "CustomError {0}");752  });753  handleAllErrors(std::move(E2), [](const CustomError &CE) {754    EXPECT_EQ(CE.message(), "CustomError {0}");755  });756 757  Error E3 = joinErrors(make_error<CustomError>(0), make_error<CustomError>(1));758  EXPECT_EQ(toStringWithoutConsuming(E3), "CustomError {0}\n"759                                          "CustomError {1}");760  EXPECT_EQ(toString(std::move(E3)), "CustomError {0}\n"761                                     "CustomError {1}");762}763 764TEST(Error, Stream) {765  {766    Error OK = Error::success();767    std::string Buf;768    llvm::raw_string_ostream S(Buf);769    S << OK;770    EXPECT_EQ("success", Buf);771    consumeError(std::move(OK));772  }773  {774    Error E1 = make_error<CustomError>(0);775    std::string Buf;776    llvm::raw_string_ostream S(Buf);777    S << E1;778    EXPECT_EQ("CustomError {0}", Buf);779    consumeError(std::move(E1));780  }781}782 783TEST(Error, SucceededMatcher) {784  EXPECT_THAT_ERROR(Error::success(), Succeeded());785  EXPECT_NONFATAL_FAILURE(786      EXPECT_THAT_ERROR(make_error<CustomError>(0), Succeeded()),787      "Expected: succeeded\n  Actual: failed  (CustomError {0})");788 789  EXPECT_THAT_EXPECTED(Expected<int>(0), Succeeded());790  EXPECT_NONFATAL_FAILURE(791      EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)),792                           Succeeded()),793      "Expected: succeeded\n  Actual: failed  (CustomError {0})");794  int a = 1;795  EXPECT_THAT_EXPECTED(Expected<int &>(a), Succeeded());796}797 798TEST(Error, FailedMatcher) {799  EXPECT_THAT_ERROR(make_error<CustomError>(0), Failed());800  EXPECT_NONFATAL_FAILURE(EXPECT_THAT_ERROR(Error::success(), Failed()),801                          "Expected: failed\n  Actual: succeeded");802 803  EXPECT_THAT_ERROR(make_error<CustomError>(0), Failed<CustomError>());804  EXPECT_NONFATAL_FAILURE(805      EXPECT_THAT_ERROR(Error::success(), Failed<CustomError>()),806      "Expected: failed with Error of given type\n  Actual: succeeded");807  EXPECT_NONFATAL_FAILURE(808      EXPECT_THAT_ERROR(make_error<CustomError>(0), Failed<CustomSubError>()),809      "Error was not of given type");810  EXPECT_NONFATAL_FAILURE(811      EXPECT_THAT_ERROR(812          joinErrors(make_error<CustomError>(0), make_error<CustomError>(1)),813          Failed<CustomError>()),814      "multiple errors");815 816  EXPECT_THAT_ERROR(817      make_error<CustomError>(0),818      Failed<CustomError>(testing::Property(&CustomError::getInfo, 0)));819  EXPECT_NONFATAL_FAILURE(820      EXPECT_THAT_ERROR(821          make_error<CustomError>(0),822          Failed<CustomError>(testing::Property(&CustomError::getInfo, 1))),823      "Expected: failed with Error of given type and the error is an object "824      "whose given property is equal to 1\n"825      "  Actual: failed  (CustomError {0})");826  EXPECT_THAT_ERROR(make_error<CustomError>(0), Failed<ErrorInfoBase>());827 828  EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)), Failed());829  EXPECT_NONFATAL_FAILURE(830      EXPECT_THAT_EXPECTED(Expected<int>(0), Failed()),831      "Expected: failed\n  Actual: succeeded with value 0");832  EXPECT_THAT_EXPECTED(Expected<int &>(make_error<CustomError>(0)), Failed());833}834 835TEST(Error, HasValueMatcher) {836  EXPECT_THAT_EXPECTED(Expected<int>(0), HasValue(0));837  EXPECT_NONFATAL_FAILURE(838      EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)),839                           HasValue(0)),840      "Expected: succeeded with value (is equal to 0)\n"841      "  Actual: failed  (CustomError {0})");842  EXPECT_NONFATAL_FAILURE(843      EXPECT_THAT_EXPECTED(Expected<int>(1), HasValue(0)),844      "Expected: succeeded with value (is equal to 0)\n"845      "  Actual: succeeded with value 1, (isn't equal to 0)");846 847  int a = 1;848  EXPECT_THAT_EXPECTED(Expected<int &>(a), HasValue(testing::Eq(1)));849 850  EXPECT_THAT_EXPECTED(Expected<int>(1), HasValue(testing::Gt(0)));851  EXPECT_NONFATAL_FAILURE(852      EXPECT_THAT_EXPECTED(Expected<int>(0), HasValue(testing::Gt(1))),853      "Expected: succeeded with value (is > 1)\n"854      "  Actual: succeeded with value 0, (isn't > 1)");855  EXPECT_NONFATAL_FAILURE(856      EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)),857                           HasValue(testing::Gt(1))),858      "Expected: succeeded with value (is > 1)\n"859      "  Actual: failed  (CustomError {0})");860}861 862TEST(Error, FailedWithMessageMatcher) {863  EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)),864                       FailedWithMessage("CustomError {0}"));865 866  EXPECT_NONFATAL_FAILURE(867      EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(1)),868                           FailedWithMessage("CustomError {0}")),869      "Expected: failed with Error whose message has 1 element that is equal "870      "to \"CustomError {0}\"\n"871      "  Actual: failed  (CustomError {1})");872 873  EXPECT_NONFATAL_FAILURE(874      EXPECT_THAT_EXPECTED(Expected<int>(0),875                           FailedWithMessage("CustomError {0}")),876      "Expected: failed with Error whose message has 1 element that is equal "877      "to \"CustomError {0}\"\n"878      "  Actual: succeeded with value 0");879 880  EXPECT_NONFATAL_FAILURE(881      EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)),882                           FailedWithMessage("CustomError {0}", "CustomError {0}")),883      "Expected: failed with Error whose message has 2 elements where\n"884      "element #0 is equal to \"CustomError {0}\",\n"885      "element #1 is equal to \"CustomError {0}\"\n"886      "  Actual: failed  (CustomError {0}), which has 1 element");887 888  EXPECT_NONFATAL_FAILURE(889      EXPECT_THAT_EXPECTED(890          Expected<int>(joinErrors(make_error<CustomError>(0),891                                   make_error<CustomError>(0))),892          FailedWithMessage("CustomError {0}")),893      "Expected: failed with Error whose message has 1 element that is equal "894      "to \"CustomError {0}\"\n"895      "  Actual: failed  (CustomError {0}; CustomError {0}), which has 2 elements");896 897  EXPECT_THAT_ERROR(898      joinErrors(make_error<CustomError>(0), make_error<CustomError>(0)),899      FailedWithMessageArray(testing::SizeIs(2)));900}901 902TEST(Error, C_API) {903  EXPECT_THAT_ERROR(unwrap(wrap(Error::success())), Succeeded())904      << "Failed to round-trip Error success value via C API";905  EXPECT_THAT_ERROR(unwrap(wrap(make_error<CustomError>(0))),906                    Failed<CustomError>())907      << "Failed to round-trip Error failure value via C API";908 909  auto Err =910      wrap(make_error<StringError>("test message", inconvertibleErrorCode()));911  EXPECT_EQ(LLVMGetErrorTypeId(Err), LLVMGetStringErrorTypeId())912      << "Failed to match error type ids via C API";913  char *ErrMsg = LLVMGetErrorMessage(Err);914  EXPECT_STREQ(ErrMsg, "test message")915      << "Failed to roundtrip StringError error message via C API";916  LLVMDisposeErrorMessage(ErrMsg);917 918  bool GotCSE = false;919  bool GotCE = false;920  handleAllErrors(921    unwrap(wrap(joinErrors(make_error<CustomSubError>(42, 7),922                           make_error<CustomError>(42)))),923    [&](CustomSubError &CSE) {924      GotCSE = true;925    },926    [&](CustomError &CE) {927      GotCE = true;928    });929  EXPECT_TRUE(GotCSE) << "Failed to round-trip ErrorList via C API";930  EXPECT_TRUE(GotCE) << "Failed to round-trip ErrorList via C API";931 932  LLVMCantFail(wrap(Error::success()));933}934 935TEST(Error, FileErrorTest) {936#if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST937    EXPECT_DEATH(938      {939        Error S = Error::success();940        consumeError(createFileError("file.bin", std::move(S)));941      },942      "");943#endif944  // Not allowed, would fail at compile-time945  //consumeError(createFileError("file.bin", ErrorSuccess()));946 947  Error E1 = make_error<CustomError>(1);948  Error FE1 = createFileError("file.bin", std::move(E1));949  EXPECT_EQ(toString(std::move(FE1)), "'file.bin': CustomError {1}");950 951  Error E2 = make_error<CustomError>(2);952  Error FE2 = createFileError("file.bin", std::move(E2));953  handleAllErrors(std::move(FE2), [](const FileError &F) {954    EXPECT_EQ(F.message(), "'file.bin': CustomError {2}");955  });956 957  Error E3 = make_error<CustomError>(3);958  Error FE3 = createFileError("file.bin", std::move(E3));959  auto E31 = handleErrors(std::move(FE3), [](std::unique_ptr<FileError> F) {960    return F->takeError();961  });962  handleAllErrors(std::move(E31), [](const CustomError &C) {963    EXPECT_EQ(C.message(), "CustomError {3}");964  });965 966  Error FE4 =967      joinErrors(createFileError("file.bin", make_error<CustomError>(41)),968                 createFileError("file2.bin", make_error<CustomError>(42)));969  EXPECT_EQ(toString(std::move(FE4)), "'file.bin': CustomError {41}\n"970                                      "'file2.bin': CustomError {42}");971 972  Error FE5 = createFileError("", make_error<CustomError>(5));973  EXPECT_EQ(toString(std::move(FE5)), "'': CustomError {5}");974 975  Error FE6 = createFileError("unused", make_error<CustomError>(6));976  handleAllErrors(std::move(FE6), [](std::unique_ptr<FileError> F) {977    EXPECT_EQ(F->messageWithoutFileInfo(), "CustomError {6}");978  });979 980  Error FE7 =981      createFileError("file.bin", make_error_code(std::errc::invalid_argument),982                      "invalid argument");983  EXPECT_EQ(toString(std::move(FE7)), "'file.bin': invalid argument");984 985  StringRef Argument = "arg";986  Error FE8 =987      createFileError("file.bin", make_error_code(std::errc::invalid_argument),988                      "invalid argument '%s'", Argument.str().c_str());989  EXPECT_EQ(toString(std::move(FE8)), "'file.bin': invalid argument 'arg'");990}991 992TEST(Error, FileErrorErrorCode) {993  for (std::error_code EC : {994           make_error_code(std::errc::not_supported),995           make_error_code(std::errc::invalid_argument),996           make_error_code(std::errc::no_such_file_or_directory),997       }) {998    EXPECT_EQ(EC, errorToErrorCode(999                      createFileError("file.bin", EC)));1000    EXPECT_EQ(EC, errorToErrorCode(1001                      createFileError("file.bin", /*Line=*/5, EC)));1002    EXPECT_EQ(EC, errorToErrorCode(1003                      createFileError("file.bin", errorCodeToError(EC))));1004    EXPECT_EQ(EC, errorToErrorCode(1005                      createFileError("file.bin", /*Line=*/5, errorCodeToError(EC))));1006  }1007 1008  // inconvertibleErrorCode() should be wrapped to avoid a fatal error.1009  EXPECT_EQ(1010      "A file error occurred.",1011      errorToErrorCode(createFileError("file.bin", inconvertibleErrorCode()))1012          .message());1013  EXPECT_EQ(1014      "A file error occurred.",1015      errorToErrorCode(createFileError("file.bin", /*Line=*/5, inconvertibleErrorCode()))1016          .message());1017}1018 1019enum class test_error_code {1020  unspecified = 1,1021  error_1,1022  error_2,1023};1024 1025} // end anon namespace1026 1027namespace std {1028    template <>1029    struct is_error_code_enum<test_error_code> : std::true_type {};1030} // namespace std1031 1032namespace {1033 1034const std::error_category &TErrorCategory();1035 1036inline std::error_code make_error_code(test_error_code E) {1037    return std::error_code(static_cast<int>(E), TErrorCategory());1038}1039 1040class TestDebugError : public ErrorInfo<TestDebugError, StringError> {1041public:1042    using ErrorInfo<TestDebugError, StringError >::ErrorInfo; // inherit constructors1043    TestDebugError(const Twine &S) : ErrorInfo(S, test_error_code::unspecified) {}1044    static char ID;1045};1046 1047class TestErrorCategory : public std::error_category {1048public:1049  const char *name() const noexcept override { return "error"; }1050  std::string message(int Condition) const override {1051    switch (static_cast<test_error_code>(Condition)) {1052    case test_error_code::unspecified:1053      return "An unknown error has occurred.";1054    case test_error_code::error_1:1055      return "Error 1.";1056    case test_error_code::error_2:1057      return "Error 2.";1058    }1059    llvm_unreachable("Unrecognized test_error_code");1060  }1061};1062 1063const std::error_category &TErrorCategory() {1064  static TestErrorCategory TestErrCategory;1065  return TestErrCategory;1066}1067 1068char TestDebugError::ID;1069 1070TEST(Error, SubtypeStringErrorTest) {1071  auto E1 = make_error<TestDebugError>(test_error_code::error_1);1072  EXPECT_EQ(toString(std::move(E1)), "Error 1.");1073 1074  auto E2 = make_error<TestDebugError>(test_error_code::error_1,1075                                       "Detailed information");1076  EXPECT_EQ(toString(std::move(E2)), "Error 1. Detailed information");1077 1078  auto E3 = make_error<TestDebugError>(test_error_code::error_2);1079  handleAllErrors(std::move(E3), [](const TestDebugError &F) {1080    EXPECT_EQ(F.message(), "Error 2.");1081  });1082 1083  auto E4 = joinErrors(make_error<TestDebugError>(test_error_code::error_1,1084                                                  "Detailed information"),1085                       make_error<TestDebugError>(test_error_code::error_2));1086  EXPECT_EQ(toString(std::move(E4)), "Error 1. Detailed information\n"1087                                     "Error 2.");1088}1089 1090static Error createAnyError() {1091  return errorCodeToError(test_error_code::unspecified);1092}1093 1094struct MoveOnlyBox {1095  std::optional<int> Box;1096 1097  explicit MoveOnlyBox(int I) : Box(I) {}1098  MoveOnlyBox() = default;1099  MoveOnlyBox(MoveOnlyBox &&) = default;1100  MoveOnlyBox &operator=(MoveOnlyBox &&) = default;1101 1102  MoveOnlyBox(const MoveOnlyBox &) = delete;1103  MoveOnlyBox &operator=(const MoveOnlyBox &) = delete;1104 1105  bool operator==(const MoveOnlyBox &RHS) const {1106    if (bool(Box) != bool(RHS.Box))1107      return false;1108    return Box ? *Box == *RHS.Box : false;1109  }1110};1111 1112TEST(Error, moveInto) {1113  // Use MoveOnlyBox as the T in Expected<T>.1114  auto make = [](int I) -> Expected<MoveOnlyBox> { return MoveOnlyBox(I); };1115  auto makeFailure = []() -> Expected<MoveOnlyBox> { return createAnyError(); };1116 1117  {1118    MoveOnlyBox V;1119 1120    // Failure with no prior value.1121    EXPECT_THAT_ERROR(makeFailure().moveInto(V), Failed());1122    EXPECT_EQ(std::nullopt, V.Box);1123 1124    // Success with no prior value.1125    EXPECT_THAT_ERROR(make(5).moveInto(V), Succeeded());1126    EXPECT_EQ(5, V.Box);1127 1128    // Success with an existing value.1129    EXPECT_THAT_ERROR(make(7).moveInto(V), Succeeded());1130    EXPECT_EQ(7, V.Box);1131 1132    // Failure with an existing value. Might be nice to assign a1133    // default-constructed value in this case, but for now it's being left1134    // alone.1135    EXPECT_THAT_ERROR(makeFailure().moveInto(V), Failed());1136    EXPECT_EQ(7, V.Box);1137  }1138 1139  // Check that this works with optionals too.1140  {1141    // Same cases as above.1142    std::optional<MoveOnlyBox> MaybeV;1143    EXPECT_THAT_ERROR(makeFailure().moveInto(MaybeV), Failed());1144    EXPECT_EQ(std::nullopt, MaybeV);1145 1146    EXPECT_THAT_ERROR(make(5).moveInto(MaybeV), Succeeded());1147    EXPECT_EQ(MoveOnlyBox(5), MaybeV);1148 1149    EXPECT_THAT_ERROR(make(7).moveInto(MaybeV), Succeeded());1150    EXPECT_EQ(MoveOnlyBox(7), MaybeV);1151 1152    EXPECT_THAT_ERROR(makeFailure().moveInto(MaybeV), Failed());1153    EXPECT_EQ(MoveOnlyBox(7), MaybeV);1154  }1155}1156 1157TEST(Error, FatalBadAllocErrorHandlersInteraction) {1158  auto ErrorHandler = [](void *Data, const char *, bool) {};1159  install_fatal_error_handler(ErrorHandler, nullptr);1160  // The following call should not crash; previously, a bug in1161  // install_bad_alloc_error_handler asserted that no fatal-error handler is1162  // installed already.1163  install_bad_alloc_error_handler(ErrorHandler, nullptr);1164 1165  // Don't interfere with other tests.1166  remove_fatal_error_handler();1167  remove_bad_alloc_error_handler();1168}1169 1170TEST(Error, BadAllocFatalErrorHandlersInteraction) {1171  auto ErrorHandler = [](void *Data, const char *, bool) {};1172  install_bad_alloc_error_handler(ErrorHandler, nullptr);1173  // The following call should not crash; related to1174  // FatalBadAllocErrorHandlersInteraction: Ensure that the error does not occur1175  // in the other direction.1176  install_fatal_error_handler(ErrorHandler, nullptr);1177 1178  // Don't interfere with other tests.1179  remove_fatal_error_handler();1180  remove_bad_alloc_error_handler();1181}1182 1183TEST(Error, ForwardToExpected) {1184  auto ErrorReturningFct = [](bool Fail) {1185    return Fail ? make_error<StringError>(llvm::errc::invalid_argument,1186                                          "Some Error")1187                : Error::success();1188  };1189  auto ExpectedReturningFct = [&](bool Fail) -> Expected<int> {1190    auto Err = ErrorReturningFct(Fail);1191    if (Err)1192      return Err;1193    return 42;1194  };1195  std::optional<int> MaybeV;1196  EXPECT_THAT_ERROR(ExpectedReturningFct(true).moveInto(MaybeV), Failed());1197  EXPECT_THAT_ERROR(ExpectedReturningFct(false).moveInto(MaybeV), Succeeded());1198  EXPECT_EQ(*MaybeV, 42);1199}1200} // namespace1201