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