| //===- unittests/ErrorOrTest.cpp - ErrorOr.h tests ------------------------===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "llvm/Support/ErrorOr.h" |
| #include "llvm/Support/Errc.h" |
| #include "gtest/gtest.h" |
| #include <memory> |
| |
| using namespace llvm; |
| |
| namespace { |
| |
| ErrorOr<int> t1() { return 1; } |
| ErrorOr<int> t2() { return errc::invalid_argument; } |
| |
| TEST(ErrorOr, SimpleValue) { |
| ErrorOr<int> a = t1(); |
| // FIXME: This is probably a bug in gtest. EXPECT_TRUE should expand to |
| // include the !! to make it friendly to explicit bool operators. |
| EXPECT_TRUE(!!a); |
| EXPECT_EQ(1, *a); |
| |
| ErrorOr<int> b = a; |
| EXPECT_EQ(1, *b); |
| |
| a = t2(); |
| EXPECT_FALSE(a); |
| EXPECT_EQ(a.getError(), errc::invalid_argument); |
| #ifdef EXPECT_DEBUG_DEATH |
| EXPECT_DEBUG_DEATH(*a, "Cannot get value when an error exists"); |
| #endif |
| } |
| |
| ErrorOr<std::unique_ptr<int> > t3() { |
| return std::unique_ptr<int>(new int(3)); |
| } |
| |
| TEST(ErrorOr, Types) { |
| int x; |
| ErrorOr<int&> a(x); |
| *a = 42; |
| EXPECT_EQ(42, x); |
| |
| // Move only types. |
| EXPECT_EQ(3, **t3()); |
| } |
| |
| struct B {}; |
| struct D : B {}; |
| |
| TEST(ErrorOr, Covariant) { |
| ErrorOr<B*> b(ErrorOr<D*>(nullptr)); |
| b = ErrorOr<D*>(nullptr); |
| |
| ErrorOr<std::unique_ptr<B> > b1(ErrorOr<std::unique_ptr<D> >(nullptr)); |
| b1 = ErrorOr<std::unique_ptr<D> >(nullptr); |
| |
| ErrorOr<std::unique_ptr<int>> b2(ErrorOr<int *>(nullptr)); |
| ErrorOr<int *> b3(nullptr); |
| ErrorOr<std::unique_ptr<int>> b4(b3); |
| } |
| |
| TEST(ErrorOr, Comparison) { |
| ErrorOr<int> x(errc::no_such_file_or_directory); |
| EXPECT_EQ(x, errc::no_such_file_or_directory); |
| } |
| |
| TEST(ErrorOr, ImplicitConversion) { |
| ErrorOr<std::string> x("string literal"); |
| EXPECT_TRUE(!!x); |
| } |
| |
| TEST(ErrorOr, ImplicitConversionCausesMove) { |
| struct Source {}; |
| struct Destination { |
| Destination(const Source&) {} |
| Destination(Source&&) = delete; |
| }; |
| Source s; |
| ErrorOr<Destination> x = s; |
| EXPECT_TRUE(!!x); |
| } |
| |
| TEST(ErrorOr, ImplicitConversionNoAmbiguity) { |
| struct CastsToErrorCode { |
| CastsToErrorCode() = default; |
| CastsToErrorCode(std::error_code) {} |
| operator std::error_code() { return errc::invalid_argument; } |
| } casts_to_error_code; |
| ErrorOr<CastsToErrorCode> x1(casts_to_error_code); |
| ErrorOr<CastsToErrorCode> x2 = casts_to_error_code; |
| ErrorOr<CastsToErrorCode> x3 = {casts_to_error_code}; |
| ErrorOr<CastsToErrorCode> x4{casts_to_error_code}; |
| ErrorOr<CastsToErrorCode> x5(errc::no_such_file_or_directory); |
| ErrorOr<CastsToErrorCode> x6 = errc::no_such_file_or_directory; |
| ErrorOr<CastsToErrorCode> x7 = {errc::no_such_file_or_directory}; |
| ErrorOr<CastsToErrorCode> x8{errc::no_such_file_or_directory}; |
| EXPECT_TRUE(!!x1); |
| EXPECT_TRUE(!!x2); |
| EXPECT_TRUE(!!x3); |
| EXPECT_TRUE(!!x4); |
| EXPECT_FALSE(x5); |
| EXPECT_FALSE(x6); |
| EXPECT_FALSE(x7); |
| EXPECT_FALSE(x8); |
| } |
| |
| // ErrorOr<int*> x(nullptr); |
| // ErrorOr<std::unique_ptr<int>> y = x; // invalid conversion |
| static_assert( |
| !std::is_convertible<const ErrorOr<int *> &, |
| ErrorOr<std::unique_ptr<int>>>::value, |
| "do not invoke explicit ctors in implicit conversion from lvalue"); |
| |
| // ErrorOr<std::unique_ptr<int>> y = ErrorOr<int*>(nullptr); // invalid |
| // // conversion |
| static_assert( |
| !std::is_convertible<ErrorOr<int *> &&, |
| ErrorOr<std::unique_ptr<int>>>::value, |
| "do not invoke explicit ctors in implicit conversion from rvalue"); |
| |
| // ErrorOr<int*> x(nullptr); |
| // ErrorOr<std::unique_ptr<int>> y; |
| // y = x; // invalid conversion |
| static_assert(!std::is_assignable<ErrorOr<std::unique_ptr<int>>&, |
| const ErrorOr<int *> &>::value, |
| "do not invoke explicit ctors in assignment"); |
| |
| // ErrorOr<std::unique_ptr<int>> x; |
| // x = ErrorOr<int*>(nullptr); // invalid conversion |
| static_assert(!std::is_assignable<ErrorOr<std::unique_ptr<int>>&, |
| ErrorOr<int *> &&>::value, |
| "do not invoke explicit ctors in assignment"); |
| } // end anon namespace |