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