blob: 6daa74f400bf5ed932e6c8b398aa765d4eb7598b [file] [log] [blame]
// Copyright 2023 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <lib/elfldltl/abi-ptr.h>
#include <lib/elfldltl/testing/typed-test.h>
#include <gtest/gtest.h>
namespace {
// Test the first default template argument.
static_assert(std::is_same_v<elfldltl::AbiPtr<int>, elfldltl::AbiPtr<int, elfldltl::Elf<>>>);
FORMAT_TYPED_TEST_SUITE(ElfldltlAbiPtrTests);
struct S {
int x;
};
template <class Ptr>
constexpr void BasicCtorAndAssignTests() {
[[maybe_unused]] constexpr Ptr default_ctor;
[[maybe_unused]] constexpr Ptr copy_ctor(default_ctor);
[[maybe_unused]] Ptr assign = default_ctor;
assign = default_ctor;
}
TYPED_TEST(ElfldltlAbiPtrTests, Basic) {
using Elf = typename TestFixture::Elf;
using LocalPtr = elfldltl::AbiPtr<const S, Elf, elfldltl::LocalAbiTraits>;
using RemotePtr = elfldltl::AbiPtr<const S, Elf, elfldltl::RemoteAbiTraits>;
static_assert(std::is_same_v<LocalPtr, elfldltl::AbiPtr<const S, Elf>>);
BasicCtorAndAssignTests<LocalPtr>();
LocalPtr local;
EXPECT_FALSE(local);
EXPECT_EQ(local.get(), nullptr);
EXPECT_EQ(local.address(), 0u);
constexpr S var = {42};
local = LocalPtr{&var};
EXPECT_TRUE(local);
EXPECT_EQ(local.address(),
static_cast<typename Elf::size_type>(reinterpret_cast<uintptr_t>(&var)));
EXPECT_EQ(local.get(), &var);
EXPECT_EQ(&(*local), &var);
EXPECT_EQ(local->x, 42);
BasicCtorAndAssignTests<RemotePtr>();
RemotePtr remote;
EXPECT_FALSE(remote);
EXPECT_EQ(remote.address(), 0u);
remote = RemotePtr::FromAddress(42);
EXPECT_TRUE(remote);
EXPECT_EQ(remote.address(), 42u);
}
template <class Ptr>
void TestComparison() {
using value_type = typename Ptr::value_type;
const Ptr one = Ptr::FromAddress(sizeof(value_type) * 1);
const Ptr two = Ptr::FromAddress(sizeof(value_type) * 2);
const Ptr also_one = one;
EXPECT_LT(one, two);
EXPECT_LE(one, two);
EXPECT_GT(two, one);
EXPECT_GE(two, one);
EXPECT_NE(one, two);
EXPECT_NE(two, one);
EXPECT_EQ(one, also_one);
EXPECT_EQ(also_one, one);
EXPECT_LE(one, also_one);
EXPECT_LE(also_one, one);
EXPECT_GE(one, also_one);
EXPECT_GE(also_one, one);
}
TYPED_TEST(ElfldltlAbiPtrTests, Comparison) {
using Elf = typename TestFixture::Elf;
using LocalPtr = elfldltl::AbiPtr<const S, Elf, elfldltl::LocalAbiTraits>;
using RemotePtr = elfldltl::AbiPtr<const S, Elf, elfldltl::RemoteAbiTraits>;
TestComparison<LocalPtr>();
TestComparison<RemotePtr>();
}
template <class Ptr>
void TestArithmetic() {
using value_type = typename Ptr::value_type;
const Ptr one = Ptr::FromAddress(sizeof(value_type) * 1);
const Ptr two = Ptr::FromAddress(sizeof(value_type) * 2);
EXPECT_EQ(one + 1, two);
EXPECT_EQ(two - 1, one);
EXPECT_EQ(two - one, 1u);
Ptr x = one;
x += 1;
EXPECT_EQ(x, two);
x -= 1;
EXPECT_EQ(x, one);
}
TYPED_TEST(ElfldltlAbiPtrTests, Arithmetic) {
using Elf = typename TestFixture::Elf;
using LocalPtr = elfldltl::AbiPtr<const S, Elf, elfldltl::LocalAbiTraits>;
using RemotePtr = elfldltl::AbiPtr<const S, Elf, elfldltl::RemoteAbiTraits>;
TestArithmetic<LocalPtr>();
TestArithmetic<RemotePtr>();
}
} // namespace