xref: /llvm-project/llvm/unittests/Support/TypeTraitsTest.cpp (revision 6a684dbc4433a33e5f94fb15c9e378a2408021e0)
1 //===- TypeTraitsTest.cpp -------------------------------------------------===//
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/ADT/ArrayRef.h"
10 #include "llvm/ADT/FunctionExtras.h"
11 #include "llvm/ADT/PointerIntPair.h"
12 #include "llvm/ADT/SmallString.h"
13 #include "llvm/ADT/SmallVector.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/Support/type_traits.h"
16 #include "gtest/gtest.h"
17 #include <optional>
18 
19 namespace {
20 
21 // Compile-time tests using static assert.
22 namespace triviality {
23 
24 // Helper for compile time checking trivially copy constructible and trivially
25 // move constructible type traits.
26 template <typename T, bool IsTriviallyCopyConstructible,
27           bool IsTriviallyMoveConstructible>
TrivialityTester()28 void TrivialityTester() {
29   static_assert(std::is_trivially_copy_constructible<T>::value ==
30                     IsTriviallyCopyConstructible,
31                 "Mismatch in expected trivial copy construction!");
32   static_assert(std::is_trivially_move_constructible<T>::value ==
33                     IsTriviallyMoveConstructible,
34                 "Mismatch in expected trivial move construction!");
35 
36 #if defined(_LIBCPP_VERSION) || defined(_MSC_VER)
37   // On compilers with support for the standard traits, make sure they agree.
38   static_assert(std::is_trivially_copy_constructible<T>::value ==
39                     IsTriviallyCopyConstructible,
40                 "Mismatch in expected trivial copy construction!");
41   static_assert(std::is_trivially_move_constructible<T>::value ==
42                     IsTriviallyMoveConstructible,
43                 "Mismatch in expected trivial move construction!");
44 #endif
45 }
46 
47 template void TrivialityTester<int, true, true>();
48 template void TrivialityTester<void *, true, true>();
49 template void TrivialityTester<int &, true, true>();
50 template void TrivialityTester<int &&, false, true>();
51 
52 struct X {};
53 struct Y {
54   Y(const Y &);
55 };
56 struct Z {
57   Z(const Z &);
58   Z(Z &&);
59 };
60 struct A {
61   A(const A &) = default;
62   A(A &&);
63 };
64 struct B {
65   B(const B &);
66   B(B &&) = default;
67 };
68 
69 template void TrivialityTester<X, true, true>();
70 template void TrivialityTester<Y, false, false>();
71 template void TrivialityTester<Z, false, false>();
72 template void TrivialityTester<A, true, false>();
73 template void TrivialityTester<B, false, true>();
74 
75 template void TrivialityTester<Z &, true, true>();
76 template void TrivialityTester<A &, true, true>();
77 template void TrivialityTester<B &, true, true>();
78 template void TrivialityTester<Z &&, false, true>();
79 template void TrivialityTester<A &&, false, true>();
80 template void TrivialityTester<B &&, false, true>();
81 
TEST(Triviality,Tester)82 TEST(Triviality, Tester) {
83   TrivialityTester<int, true, true>();
84   TrivialityTester<void *, true, true>();
85   TrivialityTester<int &, true, true>();
86   TrivialityTester<int &&, false, true>();
87 
88   TrivialityTester<X, true, true>();
89   TrivialityTester<Y, false, false>();
90   TrivialityTester<Z, false, false>();
91   TrivialityTester<A, true, false>();
92   TrivialityTester<B, false, true>();
93 
94   TrivialityTester<Z &, true, true>();
95   TrivialityTester<A &, true, true>();
96   TrivialityTester<B &, true, true>();
97   TrivialityTester<Z &&, false, true>();
98   TrivialityTester<A &&, false, true>();
99   TrivialityTester<B &&, false, true>();
100 }
101 
102 // Test that the following ADT behave as expected wrt. trivially copyable trait
103 //
104 // NB: It is important that this trait behaves the same for (at least) these
105 // types for all supported compilers to prevent ABI issue when llvm is compiled
106 // with compiler A and an other project using llvm is compiled with compiler B.
107 
TEST(Triviality,ADT)108 TEST(Triviality, ADT) {
109 
110   TrivialityTester<llvm::SmallVector<int>, false, false>();
111   TrivialityTester<llvm::SmallString<8>, false, false>();
112 
113   TrivialityTester<std::function<int()>, false, false>();
114 #if !defined(__FreeBSD__)
115   TrivialityTester<std::pair<int, bool>, true, true>();
116 #endif
117   TrivialityTester<llvm::unique_function<int()>, false, false>();
118   TrivialityTester<llvm::StringRef, true, true>();
119   TrivialityTester<llvm::ArrayRef<int>, true, true>();
120   TrivialityTester<llvm::PointerIntPair<int *, 2>, true, true>();
121 #if defined(_LIBCPP_VERSION) ||                                                \
122     (defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE >= 8)
123   TrivialityTester<std::optional<int>, true, true>();
124 #endif
125 }
126 
127 } // namespace triviality
128 
129 } // end anonymous namespace
130