1 //===- unittests/ErrorOrTest.cpp - ErrorOr.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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/Support/ErrorOr.h" 10 #include "llvm/Support/Errc.h" 11 #include "gtest/gtest.h" 12 #include <memory> 13 14 using namespace llvm; 15 16 namespace { 17 18 ErrorOr<int> t1() { return 1; } 19 ErrorOr<int> t2() { return errc::invalid_argument; } 20 21 TEST(ErrorOr, SimpleValue) { 22 ErrorOr<int> a = t1(); 23 // FIXME: This is probably a bug in gtest. EXPECT_TRUE should expand to 24 // include the !! to make it friendly to explicit bool operators. 25 EXPECT_TRUE(!!a); 26 EXPECT_EQ(1, *a); 27 28 ErrorOr<int> b = a; 29 EXPECT_EQ(1, *b); 30 31 a = t2(); 32 EXPECT_FALSE(a); 33 EXPECT_EQ(a.getError(), errc::invalid_argument); 34 #ifdef EXPECT_DEBUG_DEATH 35 EXPECT_DEBUG_DEATH(*a, "Cannot get value when an error exists"); 36 #endif 37 } 38 39 ErrorOr<std::unique_ptr<int> > t3() { 40 return std::unique_ptr<int>(new int(3)); 41 } 42 43 TEST(ErrorOr, Types) { 44 int x; 45 ErrorOr<int&> a(x); 46 *a = 42; 47 EXPECT_EQ(42, x); 48 49 // Move only types. 50 EXPECT_EQ(3, **t3()); 51 } 52 53 struct B {}; 54 struct D : B {}; 55 56 TEST(ErrorOr, Covariant) { 57 ErrorOr<B*> b(ErrorOr<D*>(nullptr)); 58 b = ErrorOr<D*>(nullptr); 59 60 ErrorOr<std::unique_ptr<B> > b1(ErrorOr<std::unique_ptr<D> >(nullptr)); 61 b1 = ErrorOr<std::unique_ptr<D> >(nullptr); 62 63 ErrorOr<std::unique_ptr<int>> b2(ErrorOr<int *>(nullptr)); 64 ErrorOr<int *> b3(nullptr); 65 ErrorOr<std::unique_ptr<int>> b4(b3); 66 } 67 68 TEST(ErrorOr, Comparison) { 69 ErrorOr<int> x(errc::no_such_file_or_directory); 70 EXPECT_EQ(x, errc::no_such_file_or_directory); 71 } 72 73 TEST(ErrorOr, ImplicitConversion) { 74 ErrorOr<std::string> x("string literal"); 75 EXPECT_TRUE(!!x); 76 } 77 78 TEST(ErrorOr, ImplicitConversionCausesMove) { 79 struct Source {}; 80 struct Destination { 81 Destination(const Source&) {} 82 Destination(Source&&) = delete; 83 }; 84 Source s; 85 ErrorOr<Destination> x = s; 86 EXPECT_TRUE(!!x); 87 } 88 89 TEST(ErrorOr, ImplicitConversionNoAmbiguity) { 90 struct CastsToErrorCode { 91 CastsToErrorCode() = default; 92 CastsToErrorCode(std::error_code) {} 93 operator std::error_code() { return errc::invalid_argument; } 94 } casts_to_error_code; 95 ErrorOr<CastsToErrorCode> x1(casts_to_error_code); 96 ErrorOr<CastsToErrorCode> x2 = casts_to_error_code; 97 ErrorOr<CastsToErrorCode> x3 = {casts_to_error_code}; 98 ErrorOr<CastsToErrorCode> x4{casts_to_error_code}; 99 ErrorOr<CastsToErrorCode> x5(errc::no_such_file_or_directory); 100 ErrorOr<CastsToErrorCode> x6 = errc::no_such_file_or_directory; 101 ErrorOr<CastsToErrorCode> x7 = {errc::no_such_file_or_directory}; 102 ErrorOr<CastsToErrorCode> x8{errc::no_such_file_or_directory}; 103 EXPECT_TRUE(!!x1); 104 EXPECT_TRUE(!!x2); 105 EXPECT_TRUE(!!x3); 106 EXPECT_TRUE(!!x4); 107 EXPECT_FALSE(x5); 108 EXPECT_FALSE(x6); 109 EXPECT_FALSE(x7); 110 EXPECT_FALSE(x8); 111 } 112 113 // ErrorOr<int*> x(nullptr); 114 // ErrorOr<std::unique_ptr<int>> y = x; // invalid conversion 115 static_assert( 116 !std::is_convertible<const ErrorOr<int *> &, 117 ErrorOr<std::unique_ptr<int>>>::value, 118 "do not invoke explicit ctors in implicit conversion from lvalue"); 119 120 // ErrorOr<std::unique_ptr<int>> y = ErrorOr<int*>(nullptr); // invalid 121 // // conversion 122 static_assert( 123 !std::is_convertible<ErrorOr<int *> &&, 124 ErrorOr<std::unique_ptr<int>>>::value, 125 "do not invoke explicit ctors in implicit conversion from rvalue"); 126 127 // ErrorOr<int*> x(nullptr); 128 // ErrorOr<std::unique_ptr<int>> y; 129 // y = x; // invalid conversion 130 static_assert(!std::is_assignable<ErrorOr<std::unique_ptr<int>>&, 131 const ErrorOr<int *> &>::value, 132 "do not invoke explicit ctors in assignment"); 133 134 // ErrorOr<std::unique_ptr<int>> x; 135 // x = ErrorOr<int*>(nullptr); // invalid conversion 136 static_assert(!std::is_assignable<ErrorOr<std::unique_ptr<int>>&, 137 ErrorOr<int *> &&>::value, 138 "do not invoke explicit ctors in assignment"); 139 } // end anon namespace 140