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> |
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 | |
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 | |
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 | |