1e2760b75SDavid Blaikie //===- llvm/unittest/ADT/PointerUnionTest.cpp - Optional unit tests -------===//
2e2760b75SDavid Blaikie //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e2760b75SDavid Blaikie //
7e2760b75SDavid Blaikie //===----------------------------------------------------------------------===//
8e2760b75SDavid Blaikie
9e2760b75SDavid Blaikie #include "llvm/ADT/PointerUnion.h"
109a67b073SChandler Carruth #include "gtest/gtest.h"
11e2760b75SDavid Blaikie using namespace llvm;
12e2760b75SDavid Blaikie
13e2760b75SDavid Blaikie namespace {
14e2760b75SDavid Blaikie
15e2760b75SDavid Blaikie typedef PointerUnion<int *, float *> PU;
162948ec5cSDmitri Gribenko typedef PointerUnion<int *, float *, long long *> PU3;
172948ec5cSDmitri Gribenko typedef PointerUnion<int *, float *, long long *, double *> PU4;
18e2760b75SDavid Blaikie
19275c5fc9SChandler Carruth struct PointerUnionTest : public testing::Test {
20275c5fc9SChandler Carruth float f;
21275c5fc9SChandler Carruth int i;
22861b371eSAndrew Trick double d;
23861b371eSAndrew Trick long long l;
24e2760b75SDavid Blaikie
25a468b8ecSChandler Carruth PU a, b, c, n;
26861b371eSAndrew Trick PU3 i3, f3, l3;
27861b371eSAndrew Trick PU4 i4, f4, l4, d4;
28861b371eSAndrew Trick PU4 i4null, f4null, l4null, d4null;
29e2760b75SDavid Blaikie
PointerUnionTest__anon696c7aee0111::PointerUnionTest30861b371eSAndrew Trick PointerUnionTest()
31861b371eSAndrew Trick : f(3.14f), i(42), d(3.14), l(42), a(&f), b(&i), c(&i), n(), i3(&i),
32861b371eSAndrew Trick f3(&f), l3(&l), i4(&i), f4(&f), l4(&l), d4(&d), i4null((int *)nullptr),
33861b371eSAndrew Trick f4null((float *)nullptr), l4null((long long *)nullptr),
34861b371eSAndrew Trick d4null((double *)nullptr) {}
35275c5fc9SChandler Carruth };
36e2760b75SDavid Blaikie
TEST_F(PointerUnionTest,Comparison)37e2760b75SDavid Blaikie TEST_F(PointerUnionTest, Comparison) {
38a468b8ecSChandler Carruth EXPECT_TRUE(a == a);
39a468b8ecSChandler Carruth EXPECT_FALSE(a != a);
40e2760b75SDavid Blaikie EXPECT_TRUE(a != b);
41e2760b75SDavid Blaikie EXPECT_FALSE(a == b);
42a468b8ecSChandler Carruth EXPECT_TRUE(b == c);
43a468b8ecSChandler Carruth EXPECT_FALSE(b != c);
44e2760b75SDavid Blaikie EXPECT_TRUE(b != n);
45e2760b75SDavid Blaikie EXPECT_FALSE(b == n);
46861b371eSAndrew Trick EXPECT_TRUE(i3 == i3);
47861b371eSAndrew Trick EXPECT_FALSE(i3 != i3);
48861b371eSAndrew Trick EXPECT_TRUE(i3 != f3);
49861b371eSAndrew Trick EXPECT_TRUE(f3 != l3);
50861b371eSAndrew Trick EXPECT_TRUE(i4 == i4);
51861b371eSAndrew Trick EXPECT_FALSE(i4 != i4);
52861b371eSAndrew Trick EXPECT_TRUE(i4 != f4);
53861b371eSAndrew Trick EXPECT_TRUE(i4 != l4);
54861b371eSAndrew Trick EXPECT_TRUE(f4 != l4);
55861b371eSAndrew Trick EXPECT_TRUE(l4 != d4);
56861b371eSAndrew Trick EXPECT_TRUE(i4null != f4null);
57861b371eSAndrew Trick EXPECT_TRUE(i4null != l4null);
58861b371eSAndrew Trick EXPECT_TRUE(i4null != d4null);
59e2760b75SDavid Blaikie }
60e2760b75SDavid Blaikie
TEST_F(PointerUnionTest,Null)61e2760b75SDavid Blaikie TEST_F(PointerUnionTest, Null) {
62e2760b75SDavid Blaikie EXPECT_FALSE(a.isNull());
63e2760b75SDavid Blaikie EXPECT_FALSE(b.isNull());
64e2760b75SDavid Blaikie EXPECT_TRUE(n.isNull());
65e2760b75SDavid Blaikie EXPECT_FALSE(!a);
66e2760b75SDavid Blaikie EXPECT_FALSE(!b);
67e2760b75SDavid Blaikie EXPECT_TRUE(!n);
68e2760b75SDavid Blaikie // workaround an issue with EXPECT macros and explicit bool
69e2760b75SDavid Blaikie EXPECT_TRUE((bool)a);
70e2760b75SDavid Blaikie EXPECT_TRUE((bool)b);
71e2760b75SDavid Blaikie EXPECT_FALSE(n);
72d24465f4SChandler Carruth
73d24465f4SChandler Carruth EXPECT_NE(n, b);
74d24465f4SChandler Carruth EXPECT_EQ(b, c);
75d24465f4SChandler Carruth b = nullptr;
76d24465f4SChandler Carruth EXPECT_EQ(n, b);
77d24465f4SChandler Carruth EXPECT_NE(b, c);
78861b371eSAndrew Trick EXPECT_FALSE(i3.isNull());
79861b371eSAndrew Trick EXPECT_FALSE(f3.isNull());
80861b371eSAndrew Trick EXPECT_FALSE(l3.isNull());
81861b371eSAndrew Trick EXPECT_FALSE(i4.isNull());
82861b371eSAndrew Trick EXPECT_FALSE(f4.isNull());
83861b371eSAndrew Trick EXPECT_FALSE(l4.isNull());
84861b371eSAndrew Trick EXPECT_FALSE(d4.isNull());
85861b371eSAndrew Trick EXPECT_TRUE(i4null.isNull());
86861b371eSAndrew Trick EXPECT_TRUE(f4null.isNull());
87861b371eSAndrew Trick EXPECT_TRUE(l4null.isNull());
88861b371eSAndrew Trick EXPECT_TRUE(d4null.isNull());
89e2760b75SDavid Blaikie }
90e2760b75SDavid Blaikie
TEST_F(PointerUnionTest,Is)91e2760b75SDavid Blaikie TEST_F(PointerUnionTest, Is) {
92e2760b75SDavid Blaikie EXPECT_FALSE(a.is<int *>());
93e2760b75SDavid Blaikie EXPECT_TRUE(a.is<float *>());
94e2760b75SDavid Blaikie EXPECT_TRUE(b.is<int *>());
95e2760b75SDavid Blaikie EXPECT_FALSE(b.is<float *>());
96e2760b75SDavid Blaikie EXPECT_TRUE(n.is<int *>());
97e2760b75SDavid Blaikie EXPECT_FALSE(n.is<float *>());
98861b371eSAndrew Trick EXPECT_TRUE(i3.is<int *>());
99861b371eSAndrew Trick EXPECT_TRUE(f3.is<float *>());
100861b371eSAndrew Trick EXPECT_TRUE(l3.is<long long *>());
101861b371eSAndrew Trick EXPECT_TRUE(i4.is<int *>());
102861b371eSAndrew Trick EXPECT_TRUE(f4.is<float *>());
103861b371eSAndrew Trick EXPECT_TRUE(l4.is<long long *>());
104861b371eSAndrew Trick EXPECT_TRUE(d4.is<double *>());
105861b371eSAndrew Trick EXPECT_TRUE(i4null.is<int *>());
106861b371eSAndrew Trick EXPECT_TRUE(f4null.is<float *>());
107861b371eSAndrew Trick EXPECT_TRUE(l4null.is<long long *>());
108861b371eSAndrew Trick EXPECT_TRUE(d4null.is<double *>());
109e2760b75SDavid Blaikie }
110e2760b75SDavid Blaikie
TEST_F(PointerUnionTest,Get)111e2760b75SDavid Blaikie TEST_F(PointerUnionTest, Get) {
112e2760b75SDavid Blaikie EXPECT_EQ(a.get<float *>(), &f);
113e2760b75SDavid Blaikie EXPECT_EQ(b.get<int *>(), &i);
11466f09ad0SCraig Topper EXPECT_EQ(n.get<int *>(), (int *)nullptr);
115e2760b75SDavid Blaikie }
116e2760b75SDavid Blaikie
1179b92875bSRichard Smith template<int I> struct alignas(8) Aligned {};
1189b92875bSRichard Smith
1199b92875bSRichard Smith typedef PointerUnion<Aligned<0> *, Aligned<1> *, Aligned<2> *, Aligned<3> *,
1209b92875bSRichard Smith Aligned<4> *, Aligned<5> *, Aligned<6> *, Aligned<7> *>
1219b92875bSRichard Smith PU8;
1229b92875bSRichard Smith
TEST_F(PointerUnionTest,ManyElements)1239b92875bSRichard Smith TEST_F(PointerUnionTest, ManyElements) {
1249b92875bSRichard Smith Aligned<0> a0;
1259b92875bSRichard Smith Aligned<7> a7;
1269b92875bSRichard Smith
1279b92875bSRichard Smith PU8 a = &a0;
1289b92875bSRichard Smith EXPECT_TRUE(a.is<Aligned<0>*>());
1299b92875bSRichard Smith EXPECT_FALSE(a.is<Aligned<1>*>());
1309b92875bSRichard Smith EXPECT_FALSE(a.is<Aligned<2>*>());
1319b92875bSRichard Smith EXPECT_FALSE(a.is<Aligned<3>*>());
1329b92875bSRichard Smith EXPECT_FALSE(a.is<Aligned<4>*>());
1339b92875bSRichard Smith EXPECT_FALSE(a.is<Aligned<5>*>());
1349b92875bSRichard Smith EXPECT_FALSE(a.is<Aligned<6>*>());
1359b92875bSRichard Smith EXPECT_FALSE(a.is<Aligned<7>*>());
136a9a92653SRichard Trieu EXPECT_EQ(a.dyn_cast<Aligned<0>*>(), &a0);
137a9a92653SRichard Trieu EXPECT_EQ(*a.getAddrOfPtr1(), &a0);
1389b92875bSRichard Smith
1399b92875bSRichard Smith a = &a7;
1409b92875bSRichard Smith EXPECT_FALSE(a.is<Aligned<0>*>());
1419b92875bSRichard Smith EXPECT_FALSE(a.is<Aligned<1>*>());
1429b92875bSRichard Smith EXPECT_FALSE(a.is<Aligned<2>*>());
1439b92875bSRichard Smith EXPECT_FALSE(a.is<Aligned<3>*>());
1449b92875bSRichard Smith EXPECT_FALSE(a.is<Aligned<4>*>());
1459b92875bSRichard Smith EXPECT_FALSE(a.is<Aligned<5>*>());
1469b92875bSRichard Smith EXPECT_FALSE(a.is<Aligned<6>*>());
1479b92875bSRichard Smith EXPECT_TRUE(a.is<Aligned<7>*>());
148a9a92653SRichard Trieu EXPECT_EQ(a.dyn_cast<Aligned<7>*>(), &a7);
1499b92875bSRichard Smith
1509b92875bSRichard Smith EXPECT_TRUE(a == PU8(&a7));
1519b92875bSRichard Smith EXPECT_TRUE(a != PU8(&a0));
1529b92875bSRichard Smith }
1539b92875bSRichard Smith
TEST_F(PointerUnionTest,GetAddrOfPtr1)154861b371eSAndrew Trick TEST_F(PointerUnionTest, GetAddrOfPtr1) {
155861b371eSAndrew Trick EXPECT_TRUE((void *)b.getAddrOfPtr1() == (void *)&b);
156861b371eSAndrew Trick EXPECT_TRUE((void *)n.getAddrOfPtr1() == (void *)&n);
157861b371eSAndrew Trick }
158861b371eSAndrew Trick
TEST_F(PointerUnionTest,NewCastInfra)159aab5bd18SSheng TEST_F(PointerUnionTest, NewCastInfra) {
160aab5bd18SSheng // test isa<>
161aab5bd18SSheng EXPECT_TRUE(isa<float *>(a));
162aab5bd18SSheng EXPECT_TRUE(isa<int *>(b));
163aab5bd18SSheng EXPECT_TRUE(isa<int *>(c));
164aab5bd18SSheng EXPECT_TRUE(isa<int *>(n));
165aab5bd18SSheng EXPECT_TRUE(isa<int *>(i3));
166aab5bd18SSheng EXPECT_TRUE(isa<float *>(f3));
167aab5bd18SSheng EXPECT_TRUE(isa<long long *>(l3));
168aab5bd18SSheng EXPECT_TRUE(isa<int *>(i4));
169aab5bd18SSheng EXPECT_TRUE(isa<float *>(f4));
170aab5bd18SSheng EXPECT_TRUE(isa<long long *>(l4));
171aab5bd18SSheng EXPECT_TRUE(isa<double *>(d4));
172aab5bd18SSheng EXPECT_TRUE(isa<int *>(i4null));
173aab5bd18SSheng EXPECT_TRUE(isa<float *>(f4null));
174aab5bd18SSheng EXPECT_TRUE(isa<long long *>(l4null));
175aab5bd18SSheng EXPECT_TRUE(isa<double *>(d4null));
176aab5bd18SSheng EXPECT_FALSE(isa<int *>(a));
177aab5bd18SSheng EXPECT_FALSE(isa<float *>(b));
178aab5bd18SSheng EXPECT_FALSE(isa<float *>(c));
179aab5bd18SSheng EXPECT_FALSE(isa<float *>(n));
180aab5bd18SSheng EXPECT_FALSE(isa<float *>(i3));
181aab5bd18SSheng EXPECT_FALSE(isa<long long *>(i3));
182aab5bd18SSheng EXPECT_FALSE(isa<int *>(f3));
183aab5bd18SSheng EXPECT_FALSE(isa<long long *>(f3));
184aab5bd18SSheng EXPECT_FALSE(isa<int *>(l3));
185aab5bd18SSheng EXPECT_FALSE(isa<float *>(l3));
186aab5bd18SSheng EXPECT_FALSE(isa<float *>(i4));
187aab5bd18SSheng EXPECT_FALSE(isa<long long *>(i4));
188aab5bd18SSheng EXPECT_FALSE(isa<double *>(i4));
189aab5bd18SSheng EXPECT_FALSE(isa<int *>(f4));
190aab5bd18SSheng EXPECT_FALSE(isa<long long *>(f4));
191aab5bd18SSheng EXPECT_FALSE(isa<double *>(f4));
192aab5bd18SSheng EXPECT_FALSE(isa<int *>(l4));
193aab5bd18SSheng EXPECT_FALSE(isa<float *>(l4));
194aab5bd18SSheng EXPECT_FALSE(isa<double *>(l4));
195aab5bd18SSheng EXPECT_FALSE(isa<int *>(d4));
196aab5bd18SSheng EXPECT_FALSE(isa<float *>(d4));
197aab5bd18SSheng EXPECT_FALSE(isa<long long *>(d4));
198aab5bd18SSheng EXPECT_FALSE(isa<float *>(i4null));
199aab5bd18SSheng EXPECT_FALSE(isa<long long *>(i4null));
200aab5bd18SSheng EXPECT_FALSE(isa<double *>(i4null));
201aab5bd18SSheng EXPECT_FALSE(isa<int *>(f4null));
202aab5bd18SSheng EXPECT_FALSE(isa<long long *>(f4null));
203aab5bd18SSheng EXPECT_FALSE(isa<double *>(f4null));
204aab5bd18SSheng EXPECT_FALSE(isa<int *>(l4null));
205aab5bd18SSheng EXPECT_FALSE(isa<float *>(l4null));
206aab5bd18SSheng EXPECT_FALSE(isa<double *>(l4null));
207aab5bd18SSheng EXPECT_FALSE(isa<int *>(d4null));
208aab5bd18SSheng EXPECT_FALSE(isa<float *>(d4null));
209aab5bd18SSheng EXPECT_FALSE(isa<long long *>(d4null));
210aab5bd18SSheng
211aab5bd18SSheng // test cast<>
212aab5bd18SSheng EXPECT_EQ(cast<float *>(a), &f);
213aab5bd18SSheng EXPECT_EQ(cast<int *>(b), &i);
214aab5bd18SSheng EXPECT_EQ(cast<int *>(c), &i);
215aab5bd18SSheng EXPECT_EQ(cast<int *>(i3), &i);
216aab5bd18SSheng EXPECT_EQ(cast<float *>(f3), &f);
217aab5bd18SSheng EXPECT_EQ(cast<long long *>(l3), &l);
218aab5bd18SSheng EXPECT_EQ(cast<int *>(i4), &i);
219aab5bd18SSheng EXPECT_EQ(cast<float *>(f4), &f);
220aab5bd18SSheng EXPECT_EQ(cast<long long *>(l4), &l);
221aab5bd18SSheng EXPECT_EQ(cast<double *>(d4), &d);
222aab5bd18SSheng
223aab5bd18SSheng // test dyn_cast
224aab5bd18SSheng EXPECT_EQ(dyn_cast<int *>(a), nullptr);
225aab5bd18SSheng EXPECT_EQ(dyn_cast<float *>(a), &f);
226aab5bd18SSheng EXPECT_EQ(dyn_cast<int *>(b), &i);
227aab5bd18SSheng EXPECT_EQ(dyn_cast<float *>(b), nullptr);
228aab5bd18SSheng EXPECT_EQ(dyn_cast<int *>(c), &i);
229aab5bd18SSheng EXPECT_EQ(dyn_cast<float *>(c), nullptr);
230aab5bd18SSheng EXPECT_EQ(dyn_cast<int *>(n), nullptr);
231aab5bd18SSheng EXPECT_EQ(dyn_cast<float *>(n), nullptr);
232aab5bd18SSheng EXPECT_EQ(dyn_cast<int *>(i3), &i);
233aab5bd18SSheng EXPECT_EQ(dyn_cast<float *>(i3), nullptr);
234aab5bd18SSheng EXPECT_EQ(dyn_cast<long long *>(i3), nullptr);
235aab5bd18SSheng EXPECT_EQ(dyn_cast<int *>(f3), nullptr);
236aab5bd18SSheng EXPECT_EQ(dyn_cast<float *>(f3), &f);
237aab5bd18SSheng EXPECT_EQ(dyn_cast<long long *>(f3), nullptr);
238aab5bd18SSheng EXPECT_EQ(dyn_cast<int *>(l3), nullptr);
239aab5bd18SSheng EXPECT_EQ(dyn_cast<float *>(l3), nullptr);
240aab5bd18SSheng EXPECT_EQ(dyn_cast<long long *>(l3), &l);
241aab5bd18SSheng EXPECT_EQ(dyn_cast<int *>(i4), &i);
242aab5bd18SSheng EXPECT_EQ(dyn_cast<float *>(i4), nullptr);
243aab5bd18SSheng EXPECT_EQ(dyn_cast<long long *>(i4), nullptr);
244aab5bd18SSheng EXPECT_EQ(dyn_cast<double *>(i4), nullptr);
245aab5bd18SSheng EXPECT_EQ(dyn_cast<int *>(f4), nullptr);
246aab5bd18SSheng EXPECT_EQ(dyn_cast<float *>(f4), &f);
247aab5bd18SSheng EXPECT_EQ(dyn_cast<long long *>(f4), nullptr);
248aab5bd18SSheng EXPECT_EQ(dyn_cast<double *>(f4), nullptr);
249aab5bd18SSheng EXPECT_EQ(dyn_cast<int *>(l4), nullptr);
250aab5bd18SSheng EXPECT_EQ(dyn_cast<float *>(l4), nullptr);
251aab5bd18SSheng EXPECT_EQ(dyn_cast<long long *>(l4), &l);
252aab5bd18SSheng EXPECT_EQ(dyn_cast<double *>(l4), nullptr);
253aab5bd18SSheng EXPECT_EQ(dyn_cast<int *>(d4), nullptr);
254aab5bd18SSheng EXPECT_EQ(dyn_cast<float *>(d4), nullptr);
255aab5bd18SSheng EXPECT_EQ(dyn_cast<long long *>(d4), nullptr);
256aab5bd18SSheng EXPECT_EQ(dyn_cast<double *>(d4), &d);
257aab5bd18SSheng EXPECT_EQ(dyn_cast<int *>(i4null), nullptr);
258aab5bd18SSheng EXPECT_EQ(dyn_cast<float *>(i4null), nullptr);
259aab5bd18SSheng EXPECT_EQ(dyn_cast<long long *>(i4null), nullptr);
260aab5bd18SSheng EXPECT_EQ(dyn_cast<double *>(i4null), nullptr);
261aab5bd18SSheng EXPECT_EQ(dyn_cast<int *>(f4null), nullptr);
262aab5bd18SSheng EXPECT_EQ(dyn_cast<float *>(f4null), nullptr);
263aab5bd18SSheng EXPECT_EQ(dyn_cast<long long *>(f4null), nullptr);
264aab5bd18SSheng EXPECT_EQ(dyn_cast<double *>(f4null), nullptr);
265aab5bd18SSheng EXPECT_EQ(dyn_cast<int *>(l4null), nullptr);
266aab5bd18SSheng EXPECT_EQ(dyn_cast<float *>(l4null), nullptr);
267aab5bd18SSheng EXPECT_EQ(dyn_cast<long long *>(l4null), nullptr);
268aab5bd18SSheng EXPECT_EQ(dyn_cast<double *>(l4null), nullptr);
269aab5bd18SSheng EXPECT_EQ(dyn_cast<int *>(d4null), nullptr);
270aab5bd18SSheng EXPECT_EQ(dyn_cast<float *>(d4null), nullptr);
271aab5bd18SSheng EXPECT_EQ(dyn_cast<long long *>(d4null), nullptr);
272aab5bd18SSheng EXPECT_EQ(dyn_cast<double *>(d4null), nullptr);
273aab5bd18SSheng
274aab5bd18SSheng // test for const
275aab5bd18SSheng const PU4 constd4(&d);
276aab5bd18SSheng EXPECT_TRUE(isa<double *>(constd4));
277aab5bd18SSheng EXPECT_FALSE(isa<int *>(constd4));
278aab5bd18SSheng EXPECT_EQ(cast<double *>(constd4), &d);
279aab5bd18SSheng EXPECT_EQ(dyn_cast<long long *>(constd4), nullptr);
280aab5bd18SSheng
281aab5bd18SSheng auto *result1 = cast<double *>(constd4);
282aab5bd18SSheng static_assert(std::is_same<double *, decltype(result1)>::value,
283aab5bd18SSheng "type mismatch for cast with PointerUnion");
284aab5bd18SSheng
285aab5bd18SSheng PointerUnion<int *, const double *> constd2(&d);
286*4f5648adSPhilip Reames auto *result2 = cast<const double *>(constd2);
287*4f5648adSPhilip Reames EXPECT_EQ(result2, &d);
288aab5bd18SSheng static_assert(std::is_same<const double *, decltype(result2)>::value,
289aab5bd18SSheng "type mismatch for cast with PointerUnion");
290aab5bd18SSheng }
291aab5bd18SSheng
292e2760b75SDavid Blaikie } // end anonymous namespace
293