[InstCombine] Signed saturation patterns
[llvm-core.git] / unittests / ADT / OptionalTest.cpp
blob1f26c101183a0fe6cc06730c128f987a6bf54a96
1 //===- llvm/unittest/ADT/OptionalTest.cpp - Optional unit 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 //===----------------------------------------------------------------------===//
9 #include "llvm/ADT/Optional.h"
10 #include "llvm/ADT/SmallString.h"
11 #include "llvm/Support/raw_ostream.h"
12 #include "gtest/gtest-spi.h"
13 #include "gtest/gtest.h"
15 #include <array>
18 using namespace llvm;
20 static_assert(is_trivially_copyable<Optional<int>>::value,
21 "trivially copyable");
23 static_assert(is_trivially_copyable<Optional<std::array<int, 3>>>::value,
24 "trivially copyable");
26 namespace {
28 struct NonDefaultConstructible {
29 static unsigned CopyConstructions;
30 static unsigned Destructions;
31 static unsigned CopyAssignments;
32 explicit NonDefaultConstructible(int) {
34 NonDefaultConstructible(const NonDefaultConstructible&) {
35 ++CopyConstructions;
37 NonDefaultConstructible &operator=(const NonDefaultConstructible&) {
38 ++CopyAssignments;
39 return *this;
41 ~NonDefaultConstructible() {
42 ++Destructions;
44 static void ResetCounts() {
45 CopyConstructions = 0;
46 Destructions = 0;
47 CopyAssignments = 0;
51 unsigned NonDefaultConstructible::CopyConstructions = 0;
52 unsigned NonDefaultConstructible::Destructions = 0;
53 unsigned NonDefaultConstructible::CopyAssignments = 0;
55 static_assert(
56 !is_trivially_copyable<Optional<NonDefaultConstructible>>::value,
57 "not trivially copyable");
59 // Test fixture
60 class OptionalTest : public testing::Test {
63 TEST_F(OptionalTest, NonDefaultConstructibleTest) {
64 Optional<NonDefaultConstructible> O;
65 EXPECT_FALSE(O);
68 TEST_F(OptionalTest, ResetTest) {
69 NonDefaultConstructible::ResetCounts();
70 Optional<NonDefaultConstructible> O(NonDefaultConstructible(3));
71 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
72 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
73 EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
74 NonDefaultConstructible::ResetCounts();
75 O.reset();
76 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
77 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
78 EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
81 TEST_F(OptionalTest, InitializationLeakTest) {
82 NonDefaultConstructible::ResetCounts();
83 Optional<NonDefaultConstructible>(NonDefaultConstructible(3));
84 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
85 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
86 EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
89 TEST_F(OptionalTest, CopyConstructionTest) {
90 NonDefaultConstructible::ResetCounts();
92 Optional<NonDefaultConstructible> A(NonDefaultConstructible(3));
93 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
94 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
95 EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
96 NonDefaultConstructible::ResetCounts();
97 Optional<NonDefaultConstructible> B(A);
98 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
99 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
100 EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
101 NonDefaultConstructible::ResetCounts();
103 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
104 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
105 EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
108 TEST_F(OptionalTest, ConstructingCopyAssignmentTest) {
109 NonDefaultConstructible::ResetCounts();
111 Optional<NonDefaultConstructible> A(NonDefaultConstructible(3));
112 Optional<NonDefaultConstructible> B;
113 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
114 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
115 EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
116 NonDefaultConstructible::ResetCounts();
117 B = A;
118 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
119 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
120 EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
121 NonDefaultConstructible::ResetCounts();
123 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
124 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
125 EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
128 TEST_F(OptionalTest, CopyingCopyAssignmentTest) {
129 NonDefaultConstructible::ResetCounts();
131 Optional<NonDefaultConstructible> A(NonDefaultConstructible(3));
132 Optional<NonDefaultConstructible> B(NonDefaultConstructible(4));
133 EXPECT_EQ(2u, NonDefaultConstructible::CopyConstructions);
134 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
135 EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
136 NonDefaultConstructible::ResetCounts();
137 B = A;
138 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
139 EXPECT_EQ(1u, NonDefaultConstructible::CopyAssignments);
140 EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
141 NonDefaultConstructible::ResetCounts();
143 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
144 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
145 EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
148 TEST_F(OptionalTest, DeletingCopyAssignmentTest) {
149 NonDefaultConstructible::ResetCounts();
151 Optional<NonDefaultConstructible> A;
152 Optional<NonDefaultConstructible> B(NonDefaultConstructible(3));
153 EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
154 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
155 EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
156 NonDefaultConstructible::ResetCounts();
157 B = A;
158 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
159 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
160 EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
161 NonDefaultConstructible::ResetCounts();
163 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
164 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
165 EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
168 TEST_F(OptionalTest, NullCopyConstructionTest) {
169 NonDefaultConstructible::ResetCounts();
171 Optional<NonDefaultConstructible> A;
172 Optional<NonDefaultConstructible> B;
173 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
174 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
175 EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
176 NonDefaultConstructible::ResetCounts();
177 B = A;
178 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
179 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
180 EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
181 NonDefaultConstructible::ResetCounts();
183 EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
184 EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
185 EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
188 TEST_F(OptionalTest, GetValueOr) {
189 Optional<int> A;
190 EXPECT_EQ(42, A.getValueOr(42));
192 A = 5;
193 EXPECT_EQ(5, A.getValueOr(42));
196 struct MultiArgConstructor {
197 int x, y;
198 MultiArgConstructor(int x, int y) : x(x), y(y) {}
199 explicit MultiArgConstructor(int x, bool positive)
200 : x(x), y(positive ? x : -x) {}
202 MultiArgConstructor(const MultiArgConstructor &) = delete;
203 MultiArgConstructor(MultiArgConstructor &&) = delete;
204 MultiArgConstructor &operator=(const MultiArgConstructor &) = delete;
205 MultiArgConstructor &operator=(MultiArgConstructor &&) = delete;
207 static unsigned Destructions;
208 ~MultiArgConstructor() {
209 ++Destructions;
211 static void ResetCounts() {
212 Destructions = 0;
215 unsigned MultiArgConstructor::Destructions = 0;
217 static_assert(
218 !is_trivially_copyable<Optional<MultiArgConstructor>>::value,
219 "not trivially copyable");
221 TEST_F(OptionalTest, Emplace) {
222 MultiArgConstructor::ResetCounts();
223 Optional<MultiArgConstructor> A;
225 A.emplace(1, 2);
226 EXPECT_TRUE(A.hasValue());
227 EXPECT_EQ(1, A->x);
228 EXPECT_EQ(2, A->y);
229 EXPECT_EQ(0u, MultiArgConstructor::Destructions);
231 A.emplace(5, false);
232 EXPECT_TRUE(A.hasValue());
233 EXPECT_EQ(5, A->x);
234 EXPECT_EQ(-5, A->y);
235 EXPECT_EQ(1u, MultiArgConstructor::Destructions);
238 struct MoveOnly {
239 static unsigned MoveConstructions;
240 static unsigned Destructions;
241 static unsigned MoveAssignments;
242 int val;
243 explicit MoveOnly(int val) : val(val) {
245 MoveOnly(MoveOnly&& other) {
246 val = other.val;
247 ++MoveConstructions;
249 MoveOnly &operator=(MoveOnly&& other) {
250 val = other.val;
251 ++MoveAssignments;
252 return *this;
254 ~MoveOnly() {
255 ++Destructions;
257 static void ResetCounts() {
258 MoveConstructions = 0;
259 Destructions = 0;
260 MoveAssignments = 0;
264 unsigned MoveOnly::MoveConstructions = 0;
265 unsigned MoveOnly::Destructions = 0;
266 unsigned MoveOnly::MoveAssignments = 0;
268 static_assert(!is_trivially_copyable<Optional<MoveOnly>>::value,
269 "not trivially copyable");
271 TEST_F(OptionalTest, MoveOnlyNull) {
272 MoveOnly::ResetCounts();
273 Optional<MoveOnly> O;
274 EXPECT_EQ(0u, MoveOnly::MoveConstructions);
275 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
276 EXPECT_EQ(0u, MoveOnly::Destructions);
279 TEST_F(OptionalTest, MoveOnlyConstruction) {
280 MoveOnly::ResetCounts();
281 Optional<MoveOnly> O(MoveOnly(3));
282 EXPECT_TRUE((bool)O);
283 EXPECT_EQ(3, O->val);
284 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
285 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
286 EXPECT_EQ(1u, MoveOnly::Destructions);
289 TEST_F(OptionalTest, MoveOnlyMoveConstruction) {
290 Optional<MoveOnly> A(MoveOnly(3));
291 MoveOnly::ResetCounts();
292 Optional<MoveOnly> B(std::move(A));
293 EXPECT_TRUE((bool)A);
294 EXPECT_TRUE((bool)B);
295 EXPECT_EQ(3, B->val);
296 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
297 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
298 EXPECT_EQ(0u, MoveOnly::Destructions);
301 TEST_F(OptionalTest, MoveOnlyAssignment) {
302 MoveOnly::ResetCounts();
303 Optional<MoveOnly> O;
304 O = MoveOnly(3);
305 EXPECT_TRUE((bool)O);
306 EXPECT_EQ(3, O->val);
307 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
308 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
309 EXPECT_EQ(1u, MoveOnly::Destructions);
312 TEST_F(OptionalTest, MoveOnlyInitializingAssignment) {
313 Optional<MoveOnly> A(MoveOnly(3));
314 Optional<MoveOnly> B;
315 MoveOnly::ResetCounts();
316 B = std::move(A);
317 EXPECT_TRUE((bool)A);
318 EXPECT_TRUE((bool)B);
319 EXPECT_EQ(3, B->val);
320 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
321 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
322 EXPECT_EQ(0u, MoveOnly::Destructions);
325 TEST_F(OptionalTest, MoveOnlyNullingAssignment) {
326 Optional<MoveOnly> A;
327 Optional<MoveOnly> B(MoveOnly(3));
328 MoveOnly::ResetCounts();
329 B = std::move(A);
330 EXPECT_FALSE((bool)A);
331 EXPECT_FALSE((bool)B);
332 EXPECT_EQ(0u, MoveOnly::MoveConstructions);
333 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
334 EXPECT_EQ(1u, MoveOnly::Destructions);
337 TEST_F(OptionalTest, MoveOnlyAssigningAssignment) {
338 Optional<MoveOnly> A(MoveOnly(3));
339 Optional<MoveOnly> B(MoveOnly(4));
340 MoveOnly::ResetCounts();
341 B = std::move(A);
342 EXPECT_TRUE((bool)A);
343 EXPECT_TRUE((bool)B);
344 EXPECT_EQ(3, B->val);
345 EXPECT_EQ(0u, MoveOnly::MoveConstructions);
346 EXPECT_EQ(1u, MoveOnly::MoveAssignments);
347 EXPECT_EQ(0u, MoveOnly::Destructions);
350 struct Immovable {
351 static unsigned Constructions;
352 static unsigned Destructions;
353 int val;
354 explicit Immovable(int val) : val(val) {
355 ++Constructions;
357 ~Immovable() {
358 ++Destructions;
360 static void ResetCounts() {
361 Constructions = 0;
362 Destructions = 0;
364 private:
365 // This should disable all move/copy operations.
366 Immovable(Immovable&& other) = delete;
369 unsigned Immovable::Constructions = 0;
370 unsigned Immovable::Destructions = 0;
372 static_assert(!is_trivially_copyable<Optional<Immovable>>::value,
373 "not trivially copyable");
375 TEST_F(OptionalTest, ImmovableEmplace) {
376 Optional<Immovable> A;
377 Immovable::ResetCounts();
378 A.emplace(4);
379 EXPECT_TRUE((bool)A);
380 EXPECT_EQ(4, A->val);
381 EXPECT_EQ(1u, Immovable::Constructions);
382 EXPECT_EQ(0u, Immovable::Destructions);
385 #if LLVM_HAS_RVALUE_REFERENCE_THIS
387 TEST_F(OptionalTest, MoveGetValueOr) {
388 Optional<MoveOnly> A;
390 MoveOnly::ResetCounts();
391 EXPECT_EQ(42, std::move(A).getValueOr(MoveOnly(42)).val);
392 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
393 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
394 EXPECT_EQ(2u, MoveOnly::Destructions);
396 A = MoveOnly(5);
397 MoveOnly::ResetCounts();
398 EXPECT_EQ(5, std::move(A).getValueOr(MoveOnly(42)).val);
399 EXPECT_EQ(1u, MoveOnly::MoveConstructions);
400 EXPECT_EQ(0u, MoveOnly::MoveAssignments);
401 EXPECT_EQ(2u, MoveOnly::Destructions);
404 #endif // LLVM_HAS_RVALUE_REFERENCE_THIS
406 struct EqualTo {
407 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
408 return X == Y;
412 struct NotEqualTo {
413 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
414 return X != Y;
418 struct Less {
419 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
420 return X < Y;
424 struct Greater {
425 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
426 return X > Y;
430 struct LessEqual {
431 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
432 return X <= Y;
436 struct GreaterEqual {
437 template <typename T, typename U> static bool apply(const T &X, const U &Y) {
438 return X >= Y;
442 template <typename OperatorT, typename T>
443 void CheckRelation(const Optional<T> &Lhs, const Optional<T> &Rhs,
444 bool Expected) {
445 EXPECT_EQ(Expected, OperatorT::apply(Lhs, Rhs));
447 if (Lhs)
448 EXPECT_EQ(Expected, OperatorT::apply(*Lhs, Rhs));
449 else
450 EXPECT_EQ(Expected, OperatorT::apply(None, Rhs));
452 if (Rhs)
453 EXPECT_EQ(Expected, OperatorT::apply(Lhs, *Rhs));
454 else
455 EXPECT_EQ(Expected, OperatorT::apply(Lhs, None));
458 struct EqualityMock {};
459 const Optional<EqualityMock> NoneEq, EqualityLhs((EqualityMock())),
460 EqualityRhs((EqualityMock()));
461 bool IsEqual;
463 bool operator==(const EqualityMock &Lhs, const EqualityMock &Rhs) {
464 EXPECT_EQ(&*EqualityLhs, &Lhs);
465 EXPECT_EQ(&*EqualityRhs, &Rhs);
466 return IsEqual;
469 TEST_F(OptionalTest, OperatorEqual) {
470 CheckRelation<EqualTo>(NoneEq, NoneEq, true);
471 CheckRelation<EqualTo>(NoneEq, EqualityRhs, false);
472 CheckRelation<EqualTo>(EqualityLhs, NoneEq, false);
474 IsEqual = false;
475 CheckRelation<EqualTo>(EqualityLhs, EqualityRhs, IsEqual);
476 IsEqual = true;
477 CheckRelation<EqualTo>(EqualityLhs, EqualityRhs, IsEqual);
480 TEST_F(OptionalTest, OperatorNotEqual) {
481 CheckRelation<NotEqualTo>(NoneEq, NoneEq, false);
482 CheckRelation<NotEqualTo>(NoneEq, EqualityRhs, true);
483 CheckRelation<NotEqualTo>(EqualityLhs, NoneEq, true);
485 IsEqual = false;
486 CheckRelation<NotEqualTo>(EqualityLhs, EqualityRhs, !IsEqual);
487 IsEqual = true;
488 CheckRelation<NotEqualTo>(EqualityLhs, EqualityRhs, !IsEqual);
491 struct InequalityMock {};
492 const Optional<InequalityMock> NoneIneq, InequalityLhs((InequalityMock())),
493 InequalityRhs((InequalityMock()));
494 bool IsLess;
496 bool operator<(const InequalityMock &Lhs, const InequalityMock &Rhs) {
497 EXPECT_EQ(&*InequalityLhs, &Lhs);
498 EXPECT_EQ(&*InequalityRhs, &Rhs);
499 return IsLess;
502 TEST_F(OptionalTest, OperatorLess) {
503 CheckRelation<Less>(NoneIneq, NoneIneq, false);
504 CheckRelation<Less>(NoneIneq, InequalityRhs, true);
505 CheckRelation<Less>(InequalityLhs, NoneIneq, false);
507 IsLess = false;
508 CheckRelation<Less>(InequalityLhs, InequalityRhs, IsLess);
509 IsLess = true;
510 CheckRelation<Less>(InequalityLhs, InequalityRhs, IsLess);
513 TEST_F(OptionalTest, OperatorGreater) {
514 CheckRelation<Greater>(NoneIneq, NoneIneq, false);
515 CheckRelation<Greater>(NoneIneq, InequalityRhs, false);
516 CheckRelation<Greater>(InequalityLhs, NoneIneq, true);
518 IsLess = false;
519 CheckRelation<Greater>(InequalityRhs, InequalityLhs, IsLess);
520 IsLess = true;
521 CheckRelation<Greater>(InequalityRhs, InequalityLhs, IsLess);
524 TEST_F(OptionalTest, OperatorLessEqual) {
525 CheckRelation<LessEqual>(NoneIneq, NoneIneq, true);
526 CheckRelation<LessEqual>(NoneIneq, InequalityRhs, true);
527 CheckRelation<LessEqual>(InequalityLhs, NoneIneq, false);
529 IsLess = false;
530 CheckRelation<LessEqual>(InequalityRhs, InequalityLhs, !IsLess);
531 IsLess = true;
532 CheckRelation<LessEqual>(InequalityRhs, InequalityLhs, !IsLess);
535 TEST_F(OptionalTest, OperatorGreaterEqual) {
536 CheckRelation<GreaterEqual>(NoneIneq, NoneIneq, true);
537 CheckRelation<GreaterEqual>(NoneIneq, InequalityRhs, false);
538 CheckRelation<GreaterEqual>(InequalityLhs, NoneIneq, true);
540 IsLess = false;
541 CheckRelation<GreaterEqual>(InequalityLhs, InequalityRhs, !IsLess);
542 IsLess = true;
543 CheckRelation<GreaterEqual>(InequalityLhs, InequalityRhs, !IsLess);
546 struct ComparableAndStreamable {
547 friend bool operator==(ComparableAndStreamable,
548 ComparableAndStreamable) LLVM_ATTRIBUTE_USED {
549 return true;
552 friend raw_ostream &operator<<(raw_ostream &OS, ComparableAndStreamable) {
553 return OS << "ComparableAndStreamable";
556 static Optional<ComparableAndStreamable> get() {
557 return ComparableAndStreamable();
561 TEST_F(OptionalTest, StreamOperator) {
562 auto to_string = [](Optional<ComparableAndStreamable> O) {
563 SmallString<16> S;
564 raw_svector_ostream OS(S);
565 OS << O;
566 return S;
568 EXPECT_EQ("ComparableAndStreamable",
569 to_string(ComparableAndStreamable::get()));
570 EXPECT_EQ("None", to_string(None));
573 struct Comparable {
574 friend bool operator==(Comparable, Comparable) LLVM_ATTRIBUTE_USED {
575 return true;
577 static Optional<Comparable> get() { return Comparable(); }
580 TEST_F(OptionalTest, UseInUnitTests) {
581 // Test that we invoke the streaming operators when pretty-printing values in
582 // EXPECT macros.
583 EXPECT_NONFATAL_FAILURE(EXPECT_EQ(llvm::None, ComparableAndStreamable::get()),
584 "Expected: llvm::None\n"
585 " Which is: None\n"
586 "To be equal to: ComparableAndStreamable::get()\n"
587 " Which is: ComparableAndStreamable");
589 // Test that it is still possible to compare objects which do not have a
590 // custom streaming operator.
591 EXPECT_NONFATAL_FAILURE(EXPECT_EQ(llvm::None, Comparable::get()), "object");
594 } // end anonymous namespace