1 | //===--------- ExecutorAddrTest.cpp - Unit tests for ExecutorAddr ---------===// |
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/ExecutionEngine/Orc/Shared/ExecutorAddress.h" |
10 | #include "OrcTestCommon.h" |
11 | |
12 | using namespace llvm; |
13 | using namespace llvm::orc; |
14 | |
15 | namespace { |
16 | |
17 | TEST(ExecutorAddrTest, DefaultAndNull) { |
18 | // Check that default constructed values and isNull behave as expected. |
19 | |
20 | ExecutorAddr Default; |
21 | ExecutorAddr Null(0); |
22 | ExecutorAddr NonNull(1); |
23 | |
24 | EXPECT_TRUE(Null.isNull()); |
25 | EXPECT_EQ(Default, Null); |
26 | |
27 | EXPECT_FALSE(NonNull.isNull()); |
28 | EXPECT_NE(Default, NonNull); |
29 | } |
30 | |
31 | TEST(ExecutorAddrTest, Ordering) { |
32 | // Check that ordering operations. |
33 | ExecutorAddr A1(1), A2(2); |
34 | |
35 | EXPECT_LE(A1, A1); |
36 | EXPECT_LT(A1, A2); |
37 | EXPECT_GT(A2, A1); |
38 | EXPECT_GE(A2, A2); |
39 | } |
40 | |
41 | TEST(ExecutorAddrTest, PtrConversion) { |
42 | // Test toPtr / fromPtr round-tripping. |
43 | int X = 0; |
44 | auto XAddr = ExecutorAddr::fromPtr(Ptr: &X); |
45 | int *XPtr = XAddr.toPtr<int *>(); |
46 | |
47 | EXPECT_EQ(XPtr, &X); |
48 | } |
49 | |
50 | static void F() {} |
51 | |
52 | TEST(ExecutorAddrTest, PtrConversionWithFunctionType) { |
53 | // Test that function types (as opposed to function pointer types) can be |
54 | // used with toPtr. |
55 | auto FAddr = ExecutorAddr::fromPtr(Ptr: F); |
56 | void (*FPtr)() = FAddr.toPtr<void()>(); |
57 | |
58 | EXPECT_EQ(FPtr, &F); |
59 | } |
60 | |
61 | TEST(ExecutorAddrTest, WrappingAndUnwrapping) { |
62 | constexpr uintptr_t RawAddr = 0x123456; |
63 | int *RawPtr = (int *)RawAddr; |
64 | |
65 | constexpr uintptr_t TagOffset = 8 * (sizeof(uintptr_t) - 1); |
66 | uintptr_t TagVal = 0xA5; |
67 | uintptr_t TagBits = TagVal << TagOffset; |
68 | void *TaggedPtr = (void *)((uintptr_t)RawPtr | TagBits); |
69 | |
70 | ExecutorAddr EA = |
71 | ExecutorAddr::fromPtr(Ptr: TaggedPtr, Unwrap: ExecutorAddr::Untag(8, TagOffset)); |
72 | |
73 | EXPECT_EQ(EA.getValue(), RawAddr); |
74 | |
75 | void *ReconstitutedTaggedPtr = |
76 | EA.toPtr<void *>(Wrap: ExecutorAddr::Tag(TagVal, TagOffset)); |
77 | |
78 | EXPECT_EQ(TaggedPtr, ReconstitutedTaggedPtr); |
79 | } |
80 | |
81 | TEST(ExecutorAddrTest, AddrRanges) { |
82 | ExecutorAddr A0(0), A1(1), A2(2), A3(3); |
83 | ExecutorAddrRange R0(A0, A1), R1(A1, A2), R2(A2, A3), R3(A0, A2), R4(A1, A3); |
84 | // 012 |
85 | // R0: # -- Before R1 |
86 | // R1: # -- |
87 | // R2: # -- After R1 |
88 | // R3: ## -- Overlaps R1 start |
89 | // R4: ## -- Overlaps R1 end |
90 | |
91 | EXPECT_EQ(R1, ExecutorAddrRange(A1, A2)); |
92 | EXPECT_EQ(R1, ExecutorAddrRange(A1, ExecutorAddrDiff(1))); |
93 | EXPECT_NE(R1, R2); |
94 | |
95 | EXPECT_TRUE(R1.contains(A1)); |
96 | EXPECT_FALSE(R1.contains(A0)); |
97 | EXPECT_FALSE(R1.contains(A2)); |
98 | |
99 | EXPECT_FALSE(R1.overlaps(R0)); |
100 | EXPECT_FALSE(R1.overlaps(R2)); |
101 | EXPECT_TRUE(R1.overlaps(R3)); |
102 | EXPECT_TRUE(R1.overlaps(R4)); |
103 | |
104 | EXPECT_LE(R0, R0); |
105 | EXPECT_LT(R0, R1); |
106 | EXPECT_GE(R0, R0); |
107 | EXPECT_GT(R1, R0); |
108 | } |
109 | |
110 | } // namespace |
111 | |