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