Michael J. Spencer | 779c424 | 2013-01-20 20:32:30 +0000 | [diff] [blame] | 1 | //===- unittests/ErrorOrTest.cpp - ErrorOr.h tests ------------------------===// |
| 2 | // |
Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 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 |
Michael J. Spencer | 779c424 | 2013-01-20 20:32:30 +0000 | [diff] [blame] | 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| 9 | #include "llvm/Support/ErrorOr.h" |
Rafael Espindola | 2a826e4 | 2014-06-13 17:20:48 +0000 | [diff] [blame] | 10 | #include "llvm/Support/Errc.h" |
Michael J. Spencer | 779c424 | 2013-01-20 20:32:30 +0000 | [diff] [blame] | 11 | #include "gtest/gtest.h" |
Michael J. Spencer | 779c424 | 2013-01-20 20:32:30 +0000 | [diff] [blame] | 12 | #include <memory> |
| 13 | |
| 14 | using namespace llvm; |
| 15 | |
| 16 | namespace { |
| 17 | |
Nick Lewycky | e5fa25a | 2016-02-09 04:47:58 +0000 | [diff] [blame] | 18 | ErrorOr<int> t1() { return 1; } |
Rafael Espindola | 2a826e4 | 2014-06-13 17:20:48 +0000 | [diff] [blame] | 19 | ErrorOr<int> t2() { return errc::invalid_argument; } |
Michael J. Spencer | 779c424 | 2013-01-20 20:32:30 +0000 | [diff] [blame] | 20 | |
| 21 | TEST(ErrorOr, SimpleValue) { |
| 22 | ErrorOr<int> a = t1(); |
Rafael Espindola | 98d3c10 | 2014-01-16 23:37:23 +0000 | [diff] [blame] | 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); |
Michael J. Spencer | 779c424 | 2013-01-20 20:32:30 +0000 | [diff] [blame] | 26 | EXPECT_EQ(1, *a); |
| 27 | |
Rafael Espindola | cd56deb | 2014-01-09 19:47:39 +0000 | [diff] [blame] | 28 | ErrorOr<int> b = a; |
| 29 | EXPECT_EQ(1, *b); |
| 30 | |
Michael J. Spencer | 779c424 | 2013-01-20 20:32:30 +0000 | [diff] [blame] | 31 | a = t2(); |
| 32 | EXPECT_FALSE(a); |
Rafael Espindola | 2a826e4 | 2014-06-13 17:20:48 +0000 | [diff] [blame] | 33 | EXPECT_EQ(a.getError(), errc::invalid_argument); |
NAKAMURA Takumi | 08e028e | 2013-01-22 04:02:41 +0000 | [diff] [blame] | 34 | #ifdef EXPECT_DEBUG_DEATH |
Michael J. Spencer | 779c424 | 2013-01-20 20:32:30 +0000 | [diff] [blame] | 35 | EXPECT_DEBUG_DEATH(*a, "Cannot get value when an error exists"); |
NAKAMURA Takumi | 08e028e | 2013-01-22 04:02:41 +0000 | [diff] [blame] | 36 | #endif |
Michael J. Spencer | 779c424 | 2013-01-20 20:32:30 +0000 | [diff] [blame] | 37 | } |
| 38 | |
Michael J. Spencer | 779c424 | 2013-01-20 20:32:30 +0000 | [diff] [blame] | 39 | ErrorOr<std::unique_ptr<int> > t3() { |
| 40 | return std::unique_ptr<int>(new int(3)); |
| 41 | } |
Michael J. Spencer | 779c424 | 2013-01-20 20:32:30 +0000 | [diff] [blame] | 42 | |
| 43 | TEST(ErrorOr, Types) { |
| 44 | int x; |
| 45 | ErrorOr<int&> a(x); |
| 46 | *a = 42; |
| 47 | EXPECT_EQ(42, x); |
| 48 | |
Michael J. Spencer | 779c424 | 2013-01-20 20:32:30 +0000 | [diff] [blame] | 49 | // Move only types. |
| 50 | EXPECT_EQ(3, **t3()); |
Michael J. Spencer | 779c424 | 2013-01-20 20:32:30 +0000 | [diff] [blame] | 51 | } |
Michael J. Spencer | 18131ae | 2013-02-06 22:28:53 +0000 | [diff] [blame] | 52 | |
| 53 | struct B {}; |
| 54 | struct D : B {}; |
| 55 | |
| 56 | TEST(ErrorOr, Covariant) { |
Craig Topper | 66f09ad | 2014-06-08 22:29:17 +0000 | [diff] [blame] | 57 | ErrorOr<B*> b(ErrorOr<D*>(nullptr)); |
| 58 | b = ErrorOr<D*>(nullptr); |
Michael J. Spencer | 18131ae | 2013-02-06 22:28:53 +0000 | [diff] [blame] | 59 | |
Craig Topper | 66f09ad | 2014-06-08 22:29:17 +0000 | [diff] [blame] | 60 | ErrorOr<std::unique_ptr<B> > b1(ErrorOr<std::unique_ptr<D> >(nullptr)); |
| 61 | b1 = ErrorOr<std::unique_ptr<D> >(nullptr); |
David Blaikie | 99b96f4 | 2014-09-03 17:31:25 +0000 | [diff] [blame] | 62 | |
| 63 | ErrorOr<std::unique_ptr<int>> b2(ErrorOr<int *>(nullptr)); |
| 64 | ErrorOr<int *> b3(nullptr); |
| 65 | ErrorOr<std::unique_ptr<int>> b4(b3); |
Michael J. Spencer | 18131ae | 2013-02-06 22:28:53 +0000 | [diff] [blame] | 66 | } |
David Blaikie | 99b96f4 | 2014-09-03 17:31:25 +0000 | [diff] [blame] | 67 | |
Michael J. Spencer | abc3984 | 2015-05-21 23:15:00 +0000 | [diff] [blame] | 68 | TEST(ErrorOr, Comparison) { |
Rafael Espindola | 74f2932 | 2015-06-13 17:23:04 +0000 | [diff] [blame] | 69 | ErrorOr<int> x(errc::no_such_file_or_directory); |
| 70 | EXPECT_EQ(x, errc::no_such_file_or_directory); |
Michael J. Spencer | abc3984 | 2015-05-21 23:15:00 +0000 | [diff] [blame] | 71 | } |
| 72 | |
Nick Lewycky | e5fa25a | 2016-02-09 04:47:58 +0000 | [diff] [blame] | 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 | |
David Blaikie | 99b96f4 | 2014-09-03 17:31:25 +0000 | [diff] [blame] | 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 |
Richard Smith | 6070793 | 2018-02-02 22:29:54 +0000 | [diff] [blame] | 130 | static_assert(!std::is_assignable<ErrorOr<std::unique_ptr<int>>&, |
David Blaikie | 99b96f4 | 2014-09-03 17:31:25 +0000 | [diff] [blame] | 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 |
Richard Smith | 6070793 | 2018-02-02 22:29:54 +0000 | [diff] [blame] | 136 | static_assert(!std::is_assignable<ErrorOr<std::unique_ptr<int>>&, |
David Blaikie | 99b96f4 | 2014-09-03 17:31:25 +0000 | [diff] [blame] | 137 | ErrorOr<int *> &&>::value, |
| 138 | "do not invoke explicit ctors in assignment"); |
Michael J. Spencer | 779c424 | 2013-01-20 20:32:30 +0000 | [diff] [blame] | 139 | } // end anon namespace |