1 | //===- llvm/unittest/ADT/PointerUnionTest.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 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "llvm/ADT/PointerUnion.h" |
10 | #include "gtest/gtest.h" |
11 | using namespace llvm; |
12 | |
13 | namespace { |
14 | |
15 | typedef PointerUnion<int *, float *> PU; |
16 | typedef PointerUnion<int *, float *, long long *> PU3; |
17 | typedef PointerUnion<int *, float *, long long *, double *> PU4; |
18 | |
19 | struct PointerUnionTest : public testing::Test { |
20 | float f; |
21 | int i; |
22 | double d; |
23 | long long l; |
24 | |
25 | PU a, b, c, n; |
26 | PU3 i3, f3, l3; |
27 | PU4 i4, f4, l4, d4; |
28 | PU4 i4null, f4null, l4null, d4null; |
29 | |
30 | PointerUnionTest() |
31 | : f(3.14f), i(42), d(3.14), l(42), a(&f), b(&i), c(&i), n(), i3(&i), |
32 | f3(&f), l3(&l), i4(&i), f4(&f), l4(&l), d4(&d), i4null((int *)nullptr), |
33 | f4null((float *)nullptr), l4null((long long *)nullptr), |
34 | d4null((double *)nullptr) {} |
35 | }; |
36 | |
37 | TEST_F(PointerUnionTest, Comparison) { |
38 | EXPECT_TRUE(a == a); |
39 | EXPECT_FALSE(a != a); |
40 | EXPECT_TRUE(a != b); |
41 | EXPECT_FALSE(a == b); |
42 | EXPECT_TRUE(b == c); |
43 | EXPECT_FALSE(b != c); |
44 | EXPECT_TRUE(b != n); |
45 | EXPECT_FALSE(b == n); |
46 | EXPECT_TRUE(i3 == i3); |
47 | EXPECT_FALSE(i3 != i3); |
48 | EXPECT_TRUE(i3 != f3); |
49 | EXPECT_TRUE(f3 != l3); |
50 | EXPECT_TRUE(i4 == i4); |
51 | EXPECT_FALSE(i4 != i4); |
52 | EXPECT_TRUE(i4 != f4); |
53 | EXPECT_TRUE(i4 != l4); |
54 | EXPECT_TRUE(f4 != l4); |
55 | EXPECT_TRUE(l4 != d4); |
56 | EXPECT_TRUE(i4null != f4null); |
57 | EXPECT_TRUE(i4null != l4null); |
58 | EXPECT_TRUE(i4null != d4null); |
59 | } |
60 | |
61 | TEST_F(PointerUnionTest, Null) { |
62 | EXPECT_FALSE(a.isNull()); |
63 | EXPECT_FALSE(b.isNull()); |
64 | EXPECT_TRUE(n.isNull()); |
65 | EXPECT_FALSE(!a); |
66 | EXPECT_FALSE(!b); |
67 | EXPECT_TRUE(!n); |
68 | // workaround an issue with EXPECT macros and explicit bool |
69 | EXPECT_TRUE((bool)a); |
70 | EXPECT_TRUE((bool)b); |
71 | EXPECT_FALSE(n); |
72 | |
73 | EXPECT_NE(n, b); |
74 | EXPECT_EQ(b, c); |
75 | b = nullptr; |
76 | EXPECT_EQ(n, b); |
77 | EXPECT_NE(b, c); |
78 | EXPECT_FALSE(i3.isNull()); |
79 | EXPECT_FALSE(f3.isNull()); |
80 | EXPECT_FALSE(l3.isNull()); |
81 | EXPECT_FALSE(i4.isNull()); |
82 | EXPECT_FALSE(f4.isNull()); |
83 | EXPECT_FALSE(l4.isNull()); |
84 | EXPECT_FALSE(d4.isNull()); |
85 | EXPECT_TRUE(i4null.isNull()); |
86 | EXPECT_TRUE(f4null.isNull()); |
87 | EXPECT_TRUE(l4null.isNull()); |
88 | EXPECT_TRUE(d4null.isNull()); |
89 | } |
90 | |
91 | TEST_F(PointerUnionTest, Is) { |
92 | EXPECT_FALSE(isa<int *>(a)); |
93 | EXPECT_TRUE(isa<float *>(a)); |
94 | EXPECT_TRUE(isa<int *>(b)); |
95 | EXPECT_FALSE(isa<float *>(b)); |
96 | EXPECT_TRUE(isa<int *>(n)); |
97 | EXPECT_FALSE(isa<float *>(n)); |
98 | EXPECT_TRUE(isa<int *>(i3)); |
99 | EXPECT_TRUE(isa<float *>(f3)); |
100 | EXPECT_TRUE(isa<long long *>(l3)); |
101 | EXPECT_TRUE(isa<int *>(i4)); |
102 | EXPECT_TRUE(isa<float *>(f4)); |
103 | EXPECT_TRUE(isa<long long *>(l4)); |
104 | EXPECT_TRUE(isa<double *>(d4)); |
105 | EXPECT_TRUE(isa<int *>(i4null)); |
106 | EXPECT_TRUE(isa<float *>(f4null)); |
107 | EXPECT_TRUE(isa<long long *>(l4null)); |
108 | EXPECT_TRUE(isa<double *>(d4null)); |
109 | } |
110 | |
111 | TEST_F(PointerUnionTest, Get) { |
112 | EXPECT_EQ(cast<float *>(a), &f); |
113 | EXPECT_EQ(cast<int *>(b), &i); |
114 | EXPECT_EQ(cast<int *>(n), (int *)nullptr); |
115 | } |
116 | |
117 | template<int I> struct alignas(8) Aligned {}; |
118 | |
119 | typedef PointerUnion<Aligned<0> *, Aligned<1> *, Aligned<2> *, Aligned<3> *, |
120 | Aligned<4> *, Aligned<5> *, Aligned<6> *, Aligned<7> *> |
121 | PU8; |
122 | |
123 | TEST_F(PointerUnionTest, ManyElements) { |
124 | Aligned<0> a0; |
125 | Aligned<7> a7; |
126 | |
127 | PU8 a = &a0; |
128 | EXPECT_TRUE(isa<Aligned<0> *>(a)); |
129 | EXPECT_FALSE(isa<Aligned<1> *>(a)); |
130 | EXPECT_FALSE(isa<Aligned<2> *>(a)); |
131 | EXPECT_FALSE(isa<Aligned<3> *>(a)); |
132 | EXPECT_FALSE(isa<Aligned<4> *>(a)); |
133 | EXPECT_FALSE(isa<Aligned<5> *>(a)); |
134 | EXPECT_FALSE(isa<Aligned<6> *>(a)); |
135 | EXPECT_FALSE(isa<Aligned<7> *>(a)); |
136 | EXPECT_EQ(dyn_cast_if_present<Aligned<0> *>(a), &a0); |
137 | EXPECT_EQ(*a.getAddrOfPtr1(), &a0); |
138 | |
139 | a = &a7; |
140 | EXPECT_FALSE(isa<Aligned<0> *>(a)); |
141 | EXPECT_FALSE(isa<Aligned<1> *>(a)); |
142 | EXPECT_FALSE(isa<Aligned<2> *>(a)); |
143 | EXPECT_FALSE(isa<Aligned<3> *>(a)); |
144 | EXPECT_FALSE(isa<Aligned<4> *>(a)); |
145 | EXPECT_FALSE(isa<Aligned<5> *>(a)); |
146 | EXPECT_FALSE(isa<Aligned<6> *>(a)); |
147 | EXPECT_TRUE(isa<Aligned<7> *>(a)); |
148 | EXPECT_EQ(dyn_cast_if_present<Aligned<7> *>(a), &a7); |
149 | |
150 | EXPECT_TRUE(a == PU8(&a7)); |
151 | EXPECT_TRUE(a != PU8(&a0)); |
152 | } |
153 | |
154 | TEST_F(PointerUnionTest, GetAddrOfPtr1) { |
155 | EXPECT_TRUE((void *)b.getAddrOfPtr1() == (void *)&b); |
156 | EXPECT_TRUE((void *)n.getAddrOfPtr1() == (void *)&n); |
157 | } |
158 | |
159 | TEST_F(PointerUnionTest, NewCastInfra) { |
160 | // test isa<> |
161 | EXPECT_TRUE(isa<float *>(a)); |
162 | EXPECT_TRUE(isa<int *>(b)); |
163 | EXPECT_TRUE(isa<int *>(c)); |
164 | EXPECT_TRUE(isa<int *>(n)); |
165 | EXPECT_TRUE(isa<int *>(i3)); |
166 | EXPECT_TRUE(isa<float *>(f3)); |
167 | EXPECT_TRUE(isa<long long *>(l3)); |
168 | EXPECT_TRUE(isa<int *>(i4)); |
169 | EXPECT_TRUE(isa<float *>(f4)); |
170 | EXPECT_TRUE(isa<long long *>(l4)); |
171 | EXPECT_TRUE(isa<double *>(d4)); |
172 | EXPECT_TRUE(isa<int *>(i4null)); |
173 | EXPECT_TRUE(isa<float *>(f4null)); |
174 | EXPECT_TRUE(isa<long long *>(l4null)); |
175 | EXPECT_TRUE(isa<double *>(d4null)); |
176 | EXPECT_FALSE(isa<int *>(a)); |
177 | EXPECT_FALSE(isa<float *>(b)); |
178 | EXPECT_FALSE(isa<float *>(c)); |
179 | EXPECT_FALSE(isa<float *>(n)); |
180 | EXPECT_FALSE(isa<float *>(i3)); |
181 | EXPECT_FALSE(isa<long long *>(i3)); |
182 | EXPECT_FALSE(isa<int *>(f3)); |
183 | EXPECT_FALSE(isa<long long *>(f3)); |
184 | EXPECT_FALSE(isa<int *>(l3)); |
185 | EXPECT_FALSE(isa<float *>(l3)); |
186 | EXPECT_FALSE(isa<float *>(i4)); |
187 | EXPECT_FALSE(isa<long long *>(i4)); |
188 | EXPECT_FALSE(isa<double *>(i4)); |
189 | EXPECT_FALSE(isa<int *>(f4)); |
190 | EXPECT_FALSE(isa<long long *>(f4)); |
191 | EXPECT_FALSE(isa<double *>(f4)); |
192 | EXPECT_FALSE(isa<int *>(l4)); |
193 | EXPECT_FALSE(isa<float *>(l4)); |
194 | EXPECT_FALSE(isa<double *>(l4)); |
195 | EXPECT_FALSE(isa<int *>(d4)); |
196 | EXPECT_FALSE(isa<float *>(d4)); |
197 | EXPECT_FALSE(isa<long long *>(d4)); |
198 | EXPECT_FALSE(isa<float *>(i4null)); |
199 | EXPECT_FALSE(isa<long long *>(i4null)); |
200 | EXPECT_FALSE(isa<double *>(i4null)); |
201 | EXPECT_FALSE(isa<int *>(f4null)); |
202 | EXPECT_FALSE(isa<long long *>(f4null)); |
203 | EXPECT_FALSE(isa<double *>(f4null)); |
204 | EXPECT_FALSE(isa<int *>(l4null)); |
205 | EXPECT_FALSE(isa<float *>(l4null)); |
206 | EXPECT_FALSE(isa<double *>(l4null)); |
207 | EXPECT_FALSE(isa<int *>(d4null)); |
208 | EXPECT_FALSE(isa<float *>(d4null)); |
209 | EXPECT_FALSE(isa<long long *>(d4null)); |
210 | |
211 | // test cast<> |
212 | EXPECT_EQ(cast<float *>(a), &f); |
213 | EXPECT_EQ(cast<int *>(b), &i); |
214 | EXPECT_EQ(cast<int *>(c), &i); |
215 | EXPECT_EQ(cast<int *>(i3), &i); |
216 | EXPECT_EQ(cast<float *>(f3), &f); |
217 | EXPECT_EQ(cast<long long *>(l3), &l); |
218 | EXPECT_EQ(cast<int *>(i4), &i); |
219 | EXPECT_EQ(cast<float *>(f4), &f); |
220 | EXPECT_EQ(cast<long long *>(l4), &l); |
221 | EXPECT_EQ(cast<double *>(d4), &d); |
222 | |
223 | // test dyn_cast |
224 | EXPECT_EQ(dyn_cast<int *>(a), nullptr); |
225 | EXPECT_EQ(dyn_cast<float *>(a), &f); |
226 | EXPECT_EQ(dyn_cast<int *>(b), &i); |
227 | EXPECT_EQ(dyn_cast<float *>(b), nullptr); |
228 | EXPECT_EQ(dyn_cast<int *>(c), &i); |
229 | EXPECT_EQ(dyn_cast<float *>(c), nullptr); |
230 | EXPECT_EQ(dyn_cast_if_present<int *>(n), nullptr); |
231 | EXPECT_EQ(dyn_cast_if_present<float *>(n), nullptr); |
232 | EXPECT_EQ(dyn_cast<int *>(i3), &i); |
233 | EXPECT_EQ(dyn_cast<float *>(i3), nullptr); |
234 | EXPECT_EQ(dyn_cast<long long *>(i3), nullptr); |
235 | EXPECT_EQ(dyn_cast<int *>(f3), nullptr); |
236 | EXPECT_EQ(dyn_cast<float *>(f3), &f); |
237 | EXPECT_EQ(dyn_cast<long long *>(f3), nullptr); |
238 | EXPECT_EQ(dyn_cast<int *>(l3), nullptr); |
239 | EXPECT_EQ(dyn_cast<float *>(l3), nullptr); |
240 | EXPECT_EQ(dyn_cast<long long *>(l3), &l); |
241 | EXPECT_EQ(dyn_cast<int *>(i4), &i); |
242 | EXPECT_EQ(dyn_cast<float *>(i4), nullptr); |
243 | EXPECT_EQ(dyn_cast<long long *>(i4), nullptr); |
244 | EXPECT_EQ(dyn_cast<double *>(i4), nullptr); |
245 | EXPECT_EQ(dyn_cast<int *>(f4), nullptr); |
246 | EXPECT_EQ(dyn_cast<float *>(f4), &f); |
247 | EXPECT_EQ(dyn_cast<long long *>(f4), nullptr); |
248 | EXPECT_EQ(dyn_cast<double *>(f4), nullptr); |
249 | EXPECT_EQ(dyn_cast<int *>(l4), nullptr); |
250 | EXPECT_EQ(dyn_cast<float *>(l4), nullptr); |
251 | EXPECT_EQ(dyn_cast<long long *>(l4), &l); |
252 | EXPECT_EQ(dyn_cast<double *>(l4), nullptr); |
253 | EXPECT_EQ(dyn_cast<int *>(d4), nullptr); |
254 | EXPECT_EQ(dyn_cast<float *>(d4), nullptr); |
255 | EXPECT_EQ(dyn_cast<long long *>(d4), nullptr); |
256 | EXPECT_EQ(dyn_cast<double *>(d4), &d); |
257 | EXPECT_EQ(dyn_cast_if_present<int *>(i4null), nullptr); |
258 | EXPECT_EQ(dyn_cast_if_present<float *>(i4null), nullptr); |
259 | EXPECT_EQ(dyn_cast_if_present<long long *>(i4null), nullptr); |
260 | EXPECT_EQ(dyn_cast_if_present<double *>(i4null), nullptr); |
261 | EXPECT_EQ(dyn_cast_if_present<int *>(f4null), nullptr); |
262 | EXPECT_EQ(dyn_cast_if_present<float *>(f4null), nullptr); |
263 | EXPECT_EQ(dyn_cast_if_present<long long *>(f4null), nullptr); |
264 | EXPECT_EQ(dyn_cast_if_present<double *>(f4null), nullptr); |
265 | EXPECT_EQ(dyn_cast_if_present<int *>(l4null), nullptr); |
266 | EXPECT_EQ(dyn_cast_if_present<float *>(l4null), nullptr); |
267 | EXPECT_EQ(dyn_cast_if_present<long long *>(l4null), nullptr); |
268 | EXPECT_EQ(dyn_cast_if_present<double *>(l4null), nullptr); |
269 | EXPECT_EQ(dyn_cast_if_present<int *>(d4null), nullptr); |
270 | EXPECT_EQ(dyn_cast_if_present<float *>(d4null), nullptr); |
271 | EXPECT_EQ(dyn_cast_if_present<long long *>(d4null), nullptr); |
272 | EXPECT_EQ(dyn_cast_if_present<double *>(d4null), nullptr); |
273 | |
274 | // test for const |
275 | const PU4 constd4(&d); |
276 | EXPECT_TRUE(isa<double *>(constd4)); |
277 | EXPECT_FALSE(isa<int *>(constd4)); |
278 | EXPECT_EQ(cast<double *>(constd4), &d); |
279 | EXPECT_EQ(dyn_cast<long long *>(constd4), nullptr); |
280 | |
281 | auto *result1 = cast<double *>(Val: constd4); |
282 | static_assert(std::is_same_v<double *, decltype(result1)>, |
283 | "type mismatch for cast with PointerUnion" ); |
284 | |
285 | PointerUnion<int *, const double *> constd2(&d); |
286 | auto *result2 = cast<const double *>(Val&: constd2); |
287 | EXPECT_EQ(result2, &d); |
288 | static_assert(std::is_same_v<const double *, decltype(result2)>, |
289 | "type mismatch for cast with PointerUnion" ); |
290 | } |
291 | |
292 | } // end anonymous namespace |
293 | |