1854c3394SAlexey Lapshin //===- llvm/unittest/Support/AddresRangeTest.cpp --------------------------===//
2854c3394SAlexey Lapshin //
3854c3394SAlexey Lapshin // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4854c3394SAlexey Lapshin // See https://llvm.org/LICENSE.txt for license information.
5854c3394SAlexey Lapshin // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6854c3394SAlexey Lapshin //
7854c3394SAlexey Lapshin //===----------------------------------------------------------------------===//
8854c3394SAlexey Lapshin 
9854c3394SAlexey Lapshin #include "llvm/ADT/AddressRanges.h"
10854c3394SAlexey Lapshin #include "llvm/Testing/Support/Error.h"
11854c3394SAlexey Lapshin 
12854c3394SAlexey Lapshin #include "gmock/gmock.h"
13854c3394SAlexey Lapshin #include "gtest/gtest.h"
14854c3394SAlexey Lapshin #include <string>
15854c3394SAlexey Lapshin 
16854c3394SAlexey Lapshin using namespace llvm;
17854c3394SAlexey Lapshin 
TEST(AddressRangeTest,TestRanges)18854c3394SAlexey Lapshin TEST(AddressRangeTest, TestRanges) {
19854c3394SAlexey Lapshin   // test llvm::AddressRange.
20854c3394SAlexey Lapshin   const uint64_t StartAddr = 0x1000;
21854c3394SAlexey Lapshin   const uint64_t EndAddr = 0x2000;
22854c3394SAlexey Lapshin   // Verify constructor and API to ensure it takes start and end address.
23854c3394SAlexey Lapshin   const AddressRange Range(StartAddr, EndAddr);
24854c3394SAlexey Lapshin   EXPECT_EQ(Range.size(), EndAddr - StartAddr);
25854c3394SAlexey Lapshin 
26854c3394SAlexey Lapshin   // Verify llvm::AddressRange::contains().
27854c3394SAlexey Lapshin   EXPECT_FALSE(Range.contains(0));
28854c3394SAlexey Lapshin   EXPECT_FALSE(Range.contains(StartAddr - 1));
29854c3394SAlexey Lapshin   EXPECT_TRUE(Range.contains(StartAddr));
30854c3394SAlexey Lapshin   EXPECT_TRUE(Range.contains(EndAddr - 1));
31854c3394SAlexey Lapshin   EXPECT_FALSE(Range.contains(EndAddr));
32854c3394SAlexey Lapshin   EXPECT_FALSE(Range.contains(UINT64_MAX));
33854c3394SAlexey Lapshin 
34854c3394SAlexey Lapshin   const AddressRange RangeSame(StartAddr, EndAddr);
35854c3394SAlexey Lapshin   const AddressRange RangeDifferentStart(StartAddr + 1, EndAddr);
36854c3394SAlexey Lapshin   const AddressRange RangeDifferentEnd(StartAddr, EndAddr + 1);
37854c3394SAlexey Lapshin   const AddressRange RangeDifferentStartEnd(StartAddr + 1, EndAddr + 1);
38854c3394SAlexey Lapshin   // Test == and != with values that are the same
39854c3394SAlexey Lapshin   EXPECT_EQ(Range, RangeSame);
40854c3394SAlexey Lapshin   EXPECT_FALSE(Range != RangeSame);
41854c3394SAlexey Lapshin   // Test == and != with values that are the different
42854c3394SAlexey Lapshin   EXPECT_NE(Range, RangeDifferentStart);
43854c3394SAlexey Lapshin   EXPECT_NE(Range, RangeDifferentEnd);
44854c3394SAlexey Lapshin   EXPECT_NE(Range, RangeDifferentStartEnd);
45854c3394SAlexey Lapshin   EXPECT_FALSE(Range == RangeDifferentStart);
46854c3394SAlexey Lapshin   EXPECT_FALSE(Range == RangeDifferentEnd);
47854c3394SAlexey Lapshin   EXPECT_FALSE(Range == RangeDifferentStartEnd);
48854c3394SAlexey Lapshin 
49854c3394SAlexey Lapshin   // Test "bool operator<(const AddressRange &, const AddressRange &)".
50854c3394SAlexey Lapshin   EXPECT_FALSE(Range < RangeSame);
51854c3394SAlexey Lapshin   EXPECT_FALSE(RangeSame < Range);
52854c3394SAlexey Lapshin   EXPECT_LT(Range, RangeDifferentStart);
53854c3394SAlexey Lapshin   EXPECT_LT(Range, RangeDifferentEnd);
54854c3394SAlexey Lapshin   EXPECT_LT(Range, RangeDifferentStartEnd);
55854c3394SAlexey Lapshin   // Test "bool operator<(const AddressRange &, uint64_t)"
56854c3394SAlexey Lapshin   EXPECT_LT(Range.start(), StartAddr + 1);
57854c3394SAlexey Lapshin   // Test "bool operator<(uint64_t, const AddressRange &)"
58854c3394SAlexey Lapshin   EXPECT_LT(StartAddr - 1, Range.start());
59854c3394SAlexey Lapshin 
60854c3394SAlexey Lapshin   // Verify llvm::AddressRange::isContiguousWith() and
61854c3394SAlexey Lapshin   // llvm::AddressRange::intersects().
62854c3394SAlexey Lapshin   const AddressRange EndsBeforeRangeStart(0, StartAddr - 1);
63854c3394SAlexey Lapshin   const AddressRange EndsAtRangeStart(0, StartAddr);
64854c3394SAlexey Lapshin   const AddressRange OverlapsRangeStart(StartAddr - 1, StartAddr + 1);
65854c3394SAlexey Lapshin   const AddressRange InsideRange(StartAddr + 1, EndAddr - 1);
66854c3394SAlexey Lapshin   const AddressRange OverlapsRangeEnd(EndAddr - 1, EndAddr + 1);
67854c3394SAlexey Lapshin   const AddressRange StartsAtRangeEnd(EndAddr, EndAddr + 0x100);
68854c3394SAlexey Lapshin   const AddressRange StartsAfterRangeEnd(EndAddr + 1, EndAddr + 0x100);
69854c3394SAlexey Lapshin 
70854c3394SAlexey Lapshin   EXPECT_FALSE(Range.intersects(EndsBeforeRangeStart));
71854c3394SAlexey Lapshin   EXPECT_FALSE(Range.intersects(EndsAtRangeStart));
72854c3394SAlexey Lapshin   EXPECT_TRUE(Range.intersects(OverlapsRangeStart));
73854c3394SAlexey Lapshin   EXPECT_TRUE(Range.intersects(InsideRange));
74854c3394SAlexey Lapshin   EXPECT_TRUE(Range.intersects(OverlapsRangeEnd));
75854c3394SAlexey Lapshin   EXPECT_FALSE(Range.intersects(StartsAtRangeEnd));
76854c3394SAlexey Lapshin   EXPECT_FALSE(Range.intersects(StartsAfterRangeEnd));
77854c3394SAlexey Lapshin 
78854c3394SAlexey Lapshin   // Test the functions that maintain address ranges:
79854c3394SAlexey Lapshin   //  "bool AddressRange::contains(uint64_t Addr) const;"
80854c3394SAlexey Lapshin   //  "void AddressRanges::insert(const AddressRange &R);"
81854c3394SAlexey Lapshin   AddressRanges Ranges;
82854c3394SAlexey Lapshin   Ranges.insert(AddressRange(0x1000, 0x2000));
83854c3394SAlexey Lapshin   Ranges.insert(AddressRange(0x2000, 0x3000));
84854c3394SAlexey Lapshin   Ranges.insert(AddressRange(0x4000, 0x5000));
85854c3394SAlexey Lapshin 
86854c3394SAlexey Lapshin   EXPECT_FALSE(Ranges.contains(0));
87854c3394SAlexey Lapshin   EXPECT_FALSE(Ranges.contains(0x1000 - 1));
88854c3394SAlexey Lapshin   EXPECT_TRUE(Ranges.contains(0x1000));
89854c3394SAlexey Lapshin   EXPECT_TRUE(Ranges.contains(0x2000));
90854c3394SAlexey Lapshin   EXPECT_TRUE(Ranges.contains(0x4000));
91854c3394SAlexey Lapshin   EXPECT_TRUE(Ranges.contains(0x2000 - 1));
92854c3394SAlexey Lapshin   EXPECT_TRUE(Ranges.contains(0x3000 - 1));
93854c3394SAlexey Lapshin   EXPECT_FALSE(Ranges.contains(0x3000 + 1));
94854c3394SAlexey Lapshin   EXPECT_TRUE(Ranges.contains(0x5000 - 1));
95854c3394SAlexey Lapshin   EXPECT_FALSE(Ranges.contains(0x5000 + 1));
96854c3394SAlexey Lapshin   EXPECT_FALSE(Ranges.contains(UINT64_MAX));
97854c3394SAlexey Lapshin 
98854c3394SAlexey Lapshin   EXPECT_FALSE(Ranges.contains(AddressRange()));
99854c3394SAlexey Lapshin   EXPECT_FALSE(Ranges.contains(AddressRange(0x1000 - 1, 0x1000)));
100854c3394SAlexey Lapshin   EXPECT_FALSE(Ranges.contains(AddressRange(0x1000, 0x1000)));
101854c3394SAlexey Lapshin   EXPECT_TRUE(Ranges.contains(AddressRange(0x1000, 0x1000 + 1)));
102854c3394SAlexey Lapshin   EXPECT_TRUE(Ranges.contains(AddressRange(0x1000, 0x2000)));
103*8bb4451aSAlexey Lapshin   EXPECT_TRUE(Ranges.contains(AddressRange(0x1000, 0x2001)));
104854c3394SAlexey Lapshin   EXPECT_TRUE(Ranges.contains(AddressRange(0x2000, 0x3000)));
105854c3394SAlexey Lapshin   EXPECT_FALSE(Ranges.contains(AddressRange(0x2000, 0x3001)));
106854c3394SAlexey Lapshin   EXPECT_FALSE(Ranges.contains(AddressRange(0x3000, 0x3001)));
107854c3394SAlexey Lapshin   EXPECT_FALSE(Ranges.contains(AddressRange(0x1500, 0x4500)));
108854c3394SAlexey Lapshin   EXPECT_FALSE(Ranges.contains(AddressRange(0x5000, 0x5001)));
109854c3394SAlexey Lapshin 
110854c3394SAlexey Lapshin   // Verify that intersecting ranges get combined
111854c3394SAlexey Lapshin   Ranges.clear();
112854c3394SAlexey Lapshin   Ranges.insert(AddressRange(0x1100, 0x1F00));
113854c3394SAlexey Lapshin   // Verify a wholy contained range that is added doesn't do anything.
114854c3394SAlexey Lapshin   Ranges.insert(AddressRange(0x1500, 0x1F00));
115854c3394SAlexey Lapshin   EXPECT_EQ(Ranges.size(), 1u);
116854c3394SAlexey Lapshin   EXPECT_EQ(Ranges[0], AddressRange(0x1100, 0x1F00));
117854c3394SAlexey Lapshin 
118854c3394SAlexey Lapshin   // Verify a range that starts before and intersects gets combined.
119854c3394SAlexey Lapshin   Ranges.insert(AddressRange(0x1000, Ranges[0].start() + 1));
120854c3394SAlexey Lapshin   EXPECT_EQ(Ranges.size(), 1u);
121854c3394SAlexey Lapshin   EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x1F00));
122854c3394SAlexey Lapshin 
123854c3394SAlexey Lapshin   // Verify a range that starts inside and extends ranges gets combined.
124854c3394SAlexey Lapshin   Ranges.insert(AddressRange(Ranges[0].end() - 1, 0x2000));
125854c3394SAlexey Lapshin   EXPECT_EQ(Ranges.size(), 1u);
126854c3394SAlexey Lapshin   EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x2000));
127854c3394SAlexey Lapshin 
128*8bb4451aSAlexey Lapshin   // Verify that adjacent ranges get combined
129*8bb4451aSAlexey Lapshin   Ranges.insert(AddressRange(0x2000, 0x2fff));
130*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges.size(), 1u);
131*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x2fff));
132*8bb4451aSAlexey Lapshin 
133*8bb4451aSAlexey Lapshin   // Verify that ranges having 1 byte gap do not get combined
134*8bb4451aSAlexey Lapshin   Ranges.insert(AddressRange(0x3000, 0x4000));
135854c3394SAlexey Lapshin   EXPECT_EQ(Ranges.size(), 2u);
136*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x2fff));
137*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges[1], AddressRange(0x3000, 0x4000));
138*8bb4451aSAlexey Lapshin 
139854c3394SAlexey Lapshin   // Verify if we add an address range that intersects two ranges
140854c3394SAlexey Lapshin   // that they get combined
141854c3394SAlexey Lapshin   Ranges.insert(AddressRange(Ranges[0].end() - 1, Ranges[1].start() + 1));
142854c3394SAlexey Lapshin   EXPECT_EQ(Ranges.size(), 1u);
143*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x4000));
144854c3394SAlexey Lapshin 
145854c3394SAlexey Lapshin   Ranges.insert(AddressRange(0x3000, 0x4000));
146854c3394SAlexey Lapshin   Ranges.insert(AddressRange(0x4000, 0x5000));
147854c3394SAlexey Lapshin   Ranges.insert(AddressRange(0x2000, 0x4500));
148854c3394SAlexey Lapshin   EXPECT_EQ(Ranges.size(), 1u);
149854c3394SAlexey Lapshin   EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x5000));
150854c3394SAlexey Lapshin }
151*8bb4451aSAlexey Lapshin 
TEST(AddressRangeTest,TestRangesMap)152*8bb4451aSAlexey Lapshin TEST(AddressRangeTest, TestRangesMap) {
153*8bb4451aSAlexey Lapshin   AddressRangesMap<int> Ranges;
154*8bb4451aSAlexey Lapshin 
155*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges.size(), 0u);
156*8bb4451aSAlexey Lapshin   EXPECT_TRUE(Ranges.empty());
157*8bb4451aSAlexey Lapshin 
158*8bb4451aSAlexey Lapshin   // Add single range.
159*8bb4451aSAlexey Lapshin   Ranges.insert(AddressRange(0x1000, 0x2000), 0xfe);
160*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges.size(), 1u);
161*8bb4451aSAlexey Lapshin   EXPECT_FALSE(Ranges.empty());
162*8bb4451aSAlexey Lapshin   EXPECT_TRUE(Ranges.contains(0x1500));
163*8bb4451aSAlexey Lapshin   EXPECT_TRUE(Ranges.contains(AddressRange(0x1000, 0x2000)));
164*8bb4451aSAlexey Lapshin 
165*8bb4451aSAlexey Lapshin   // Clear ranges.
166*8bb4451aSAlexey Lapshin   Ranges.clear();
167*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges.size(), 0u);
168*8bb4451aSAlexey Lapshin   EXPECT_TRUE(Ranges.empty());
169*8bb4451aSAlexey Lapshin 
170*8bb4451aSAlexey Lapshin   // Add range and check value.
171*8bb4451aSAlexey Lapshin   Ranges.insert(AddressRange(0x1000, 0x2000), 0xfe);
172*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges.size(), 1u);
173*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges.getRangeValueThatContains(0x1000)->second, 0xfe);
174*8bb4451aSAlexey Lapshin 
175*8bb4451aSAlexey Lapshin   // Add adjacent range and check value.
176*8bb4451aSAlexey Lapshin   Ranges.insert(AddressRange(0x2000, 0x3000), 0xfc);
177*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges.size(), 1u);
178*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges.getRangeValueThatContains(0x1000)->second, 0xfc);
179*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges.getRangeValueThatContains(0x2000)->second, 0xfc);
180*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges.getRangeValueThatContains(0x2900)->second, 0xfc);
181*8bb4451aSAlexey Lapshin   EXPECT_FALSE(Ranges.getRangeValueThatContains(0x3000));
182*8bb4451aSAlexey Lapshin 
183*8bb4451aSAlexey Lapshin   // Add intersecting range and check value.
184*8bb4451aSAlexey Lapshin   Ranges.insert(AddressRange(0x2000, 0x3000), 0xff);
185*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges.size(), 1u);
186*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges.getRangeValueThatContains(0x1000)->second, 0xff);
187*8bb4451aSAlexey Lapshin 
188*8bb4451aSAlexey Lapshin   // Add second range and check values.
189*8bb4451aSAlexey Lapshin   Ranges.insert(AddressRange(0x4000, 0x5000), 0x0);
190*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges.size(), 2u);
191*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges[0].second, 0xff);
192*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges[1].second, 0x0);
193*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges.getRangeValueThatContains(0x1000)->second, 0xff);
194*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges.getRangeValueThatContains(0x4000)->second, 0x0);
195*8bb4451aSAlexey Lapshin 
196*8bb4451aSAlexey Lapshin   // Add intersecting range and check value.
197*8bb4451aSAlexey Lapshin   Ranges.insert(AddressRange(0x0, 0x6000), 0x1);
198*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges.size(), 1u);
199*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges.getRangeValueThatContains(0x1000)->second, 0x1);
200*8bb4451aSAlexey Lapshin 
201*8bb4451aSAlexey Lapshin   // Check that values are correctly preserved for combined ranges.
202*8bb4451aSAlexey Lapshin   Ranges.clear();
203*8bb4451aSAlexey Lapshin   Ranges.insert(AddressRange(0x0, 0xff), 0x1);
204*8bb4451aSAlexey Lapshin   Ranges.insert(AddressRange(0x100, 0x1ff), 0x2);
205*8bb4451aSAlexey Lapshin   Ranges.insert(AddressRange(0x200, 0x2ff), 0x3);
206*8bb4451aSAlexey Lapshin   Ranges.insert(AddressRange(0x300, 0x3ff), 0x4);
207*8bb4451aSAlexey Lapshin   Ranges.insert(AddressRange(0x400, 0x4ff), 0x5);
208*8bb4451aSAlexey Lapshin   Ranges.insert(AddressRange(0x500, 0x5ff), 0x6);
209*8bb4451aSAlexey Lapshin   Ranges.insert(AddressRange(0x600, 0x6ff), 0x7);
210*8bb4451aSAlexey Lapshin 
211*8bb4451aSAlexey Lapshin   Ranges.insert(AddressRange(0x150, 0x350), 0xff);
212*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges.size(), 5u);
213*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges[0].first, AddressRange(0x0, 0xff));
214*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges[0].second, 0x1);
215*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges[1].first, AddressRange(0x100, 0x3ff));
216*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges[1].second, 0xff);
217*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges[2].first, AddressRange(0x400, 0x4ff));
218*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges[2].second, 0x5);
219*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges[3].first, AddressRange(0x500, 0x5ff));
220*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges[3].second, 0x6);
221*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges[4].first, AddressRange(0x600, 0x6ff));
222*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges[4].second, 0x7);
223*8bb4451aSAlexey Lapshin 
224*8bb4451aSAlexey Lapshin   Ranges.insert(AddressRange(0x3ff, 0x400), 0x5);
225*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges.size(), 4u);
226*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges[0].first, AddressRange(0x0, 0xff));
227*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges[0].second, 0x1);
228*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges[1].first, AddressRange(0x100, 0x4ff));
229*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges[1].second, 0x5);
230*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges[2].first, AddressRange(0x500, 0x5ff));
231*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges[2].second, 0x6);
232*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges[3].first, AddressRange(0x600, 0x6ff));
233*8bb4451aSAlexey Lapshin   EXPECT_EQ(Ranges[3].second, 0x7);
234*8bb4451aSAlexey Lapshin }
235