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_v<const ErrorOr<int *> &, |
117 | ErrorOr<std::unique_ptr<int>>>, |
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_v<ErrorOr<int *> &&, ErrorOr<std::unique_ptr<int>>>, |
124 | "do not invoke explicit ctors in implicit conversion from rvalue" ); |
125 | |
126 | // ErrorOr<int*> x(nullptr); |
127 | // ErrorOr<std::unique_ptr<int>> y; |
128 | // y = x; // invalid conversion |
129 | static_assert(!std::is_assignable_v<ErrorOr<std::unique_ptr<int>> &, |
130 | const ErrorOr<int *> &>, |
131 | "do not invoke explicit ctors in assignment" ); |
132 | |
133 | // ErrorOr<std::unique_ptr<int>> x; |
134 | // x = ErrorOr<int*>(nullptr); // invalid conversion |
135 | static_assert( |
136 | !std::is_assignable_v<ErrorOr<std::unique_ptr<int>> &, ErrorOr<int *> &&>, |
137 | "do not invoke explicit ctors in assignment" ); |
138 | } // end anon namespace |
139 | |