llvm-project/llvm/unittests/Support/AddressRangeTest.cpp

145 lines
6.0 KiB
C++

//===- llvm/unittest/Support/AddresRangeTest.cpp --------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/ADT/AddressRanges.h"
#include "llvm/Testing/Support/Error.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <string>
using namespace llvm;
TEST(AddressRangeTest, TestRanges) {
// test llvm::AddressRange.
const uint64_t StartAddr = 0x1000;
const uint64_t EndAddr = 0x2000;
// Verify constructor and API to ensure it takes start and end address.
const AddressRange Range(StartAddr, EndAddr);
EXPECT_EQ(Range.size(), EndAddr - StartAddr);
// Verify llvm::AddressRange::contains().
EXPECT_FALSE(Range.contains(0));
EXPECT_FALSE(Range.contains(StartAddr - 1));
EXPECT_TRUE(Range.contains(StartAddr));
EXPECT_TRUE(Range.contains(EndAddr - 1));
EXPECT_FALSE(Range.contains(EndAddr));
EXPECT_FALSE(Range.contains(UINT64_MAX));
const AddressRange RangeSame(StartAddr, EndAddr);
const AddressRange RangeDifferentStart(StartAddr + 1, EndAddr);
const AddressRange RangeDifferentEnd(StartAddr, EndAddr + 1);
const AddressRange RangeDifferentStartEnd(StartAddr + 1, EndAddr + 1);
// Test == and != with values that are the same
EXPECT_EQ(Range, RangeSame);
EXPECT_FALSE(Range != RangeSame);
// Test == and != with values that are the different
EXPECT_NE(Range, RangeDifferentStart);
EXPECT_NE(Range, RangeDifferentEnd);
EXPECT_NE(Range, RangeDifferentStartEnd);
EXPECT_FALSE(Range == RangeDifferentStart);
EXPECT_FALSE(Range == RangeDifferentEnd);
EXPECT_FALSE(Range == RangeDifferentStartEnd);
// Test "bool operator<(const AddressRange &, const AddressRange &)".
EXPECT_FALSE(Range < RangeSame);
EXPECT_FALSE(RangeSame < Range);
EXPECT_LT(Range, RangeDifferentStart);
EXPECT_LT(Range, RangeDifferentEnd);
EXPECT_LT(Range, RangeDifferentStartEnd);
// Test "bool operator<(const AddressRange &, uint64_t)"
EXPECT_LT(Range.start(), StartAddr + 1);
// Test "bool operator<(uint64_t, const AddressRange &)"
EXPECT_LT(StartAddr - 1, Range.start());
// Verify llvm::AddressRange::isContiguousWith() and
// llvm::AddressRange::intersects().
const AddressRange EndsBeforeRangeStart(0, StartAddr - 1);
const AddressRange EndsAtRangeStart(0, StartAddr);
const AddressRange OverlapsRangeStart(StartAddr - 1, StartAddr + 1);
const AddressRange InsideRange(StartAddr + 1, EndAddr - 1);
const AddressRange OverlapsRangeEnd(EndAddr - 1, EndAddr + 1);
const AddressRange StartsAtRangeEnd(EndAddr, EndAddr + 0x100);
const AddressRange StartsAfterRangeEnd(EndAddr + 1, EndAddr + 0x100);
EXPECT_FALSE(Range.intersects(EndsBeforeRangeStart));
EXPECT_FALSE(Range.intersects(EndsAtRangeStart));
EXPECT_TRUE(Range.intersects(OverlapsRangeStart));
EXPECT_TRUE(Range.intersects(InsideRange));
EXPECT_TRUE(Range.intersects(OverlapsRangeEnd));
EXPECT_FALSE(Range.intersects(StartsAtRangeEnd));
EXPECT_FALSE(Range.intersects(StartsAfterRangeEnd));
// Test the functions that maintain address ranges:
// "bool AddressRange::contains(uint64_t Addr) const;"
// "void AddressRanges::insert(const AddressRange &R);"
AddressRanges Ranges;
Ranges.insert(AddressRange(0x1000, 0x2000));
Ranges.insert(AddressRange(0x2000, 0x3000));
Ranges.insert(AddressRange(0x4000, 0x5000));
EXPECT_FALSE(Ranges.contains(0));
EXPECT_FALSE(Ranges.contains(0x1000 - 1));
EXPECT_TRUE(Ranges.contains(0x1000));
EXPECT_TRUE(Ranges.contains(0x2000));
EXPECT_TRUE(Ranges.contains(0x4000));
EXPECT_TRUE(Ranges.contains(0x2000 - 1));
EXPECT_TRUE(Ranges.contains(0x3000 - 1));
EXPECT_FALSE(Ranges.contains(0x3000 + 1));
EXPECT_TRUE(Ranges.contains(0x5000 - 1));
EXPECT_FALSE(Ranges.contains(0x5000 + 1));
EXPECT_FALSE(Ranges.contains(UINT64_MAX));
EXPECT_FALSE(Ranges.contains(AddressRange()));
EXPECT_FALSE(Ranges.contains(AddressRange(0x1000 - 1, 0x1000)));
EXPECT_FALSE(Ranges.contains(AddressRange(0x1000, 0x1000)));
EXPECT_TRUE(Ranges.contains(AddressRange(0x1000, 0x1000 + 1)));
EXPECT_TRUE(Ranges.contains(AddressRange(0x1000, 0x2000)));
EXPECT_FALSE(Ranges.contains(AddressRange(0x1000, 0x2001)));
EXPECT_TRUE(Ranges.contains(AddressRange(0x2000, 0x3000)));
EXPECT_FALSE(Ranges.contains(AddressRange(0x2000, 0x3001)));
EXPECT_FALSE(Ranges.contains(AddressRange(0x3000, 0x3001)));
EXPECT_FALSE(Ranges.contains(AddressRange(0x1500, 0x4500)));
EXPECT_FALSE(Ranges.contains(AddressRange(0x5000, 0x5001)));
// Verify that intersecting ranges get combined
Ranges.clear();
Ranges.insert(AddressRange(0x1100, 0x1F00));
// Verify a wholy contained range that is added doesn't do anything.
Ranges.insert(AddressRange(0x1500, 0x1F00));
EXPECT_EQ(Ranges.size(), 1u);
EXPECT_EQ(Ranges[0], AddressRange(0x1100, 0x1F00));
// Verify a range that starts before and intersects gets combined.
Ranges.insert(AddressRange(0x1000, Ranges[0].start() + 1));
EXPECT_EQ(Ranges.size(), 1u);
EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x1F00));
// Verify a range that starts inside and extends ranges gets combined.
Ranges.insert(AddressRange(Ranges[0].end() - 1, 0x2000));
EXPECT_EQ(Ranges.size(), 1u);
EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x2000));
// Verify that adjacent ranges don't get combined
Ranges.insert(AddressRange(0x2000, 0x3000));
EXPECT_EQ(Ranges.size(), 2u);
EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x2000));
EXPECT_EQ(Ranges[1], AddressRange(0x2000, 0x3000));
// Verify if we add an address range that intersects two ranges
// that they get combined
Ranges.insert(AddressRange(Ranges[0].end() - 1, Ranges[1].start() + 1));
EXPECT_EQ(Ranges.size(), 1u);
EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x3000));
Ranges.insert(AddressRange(0x3000, 0x4000));
Ranges.insert(AddressRange(0x4000, 0x5000));
Ranges.insert(AddressRange(0x2000, 0x4500));
EXPECT_EQ(Ranges.size(), 1u);
EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x5000));
}