Files
carbon-lang/common/indirect_value_test.cpp
T
Jon Ross-Perkins c832d523be Update files and clang-tidy config to pass with clang-tidy-20 (#4691)
Disables three new warnings because they lean more towards style
conflicts than fixes. I've brought these up on #style.

Other than that, mostly fixing basic issues, and things that
clang-tidy-20 seems to fire where clang-tiday-16 didn't. One particular
curious case is `llvm::StringLiteral::data()` uses, which are flagged as
not strictly null-terminated; I'm switching to `const char*` in those
spots which matches `llvm::formatv`'s format argument, but feels worse.

I'm removing `run_clang_tidy.py` here because I'm observing it give
fewer warnings than `bazel build --config=clang-tidy -k
//toolchain/...`. The latter matches how we enforce in GitHub actions
(and also caches results, and suppresses output for files that have no
issues), so I'm dropping the bespoke script.
2024-12-17 01:25:53 +00:00

131 lines
3.4 KiB
C++

// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#include "common/indirect_value.h"
#include <gtest/gtest.h>
#include <string>
namespace Carbon {
namespace {
TEST(IndirectValueTest, ConstAccess) {
const IndirectValue<int> v = 42;
EXPECT_EQ(*v, 42);
EXPECT_EQ(v.GetPointer(), &*v);
}
TEST(IndirectValueTest, MutableAccess) {
IndirectValue<int> v = 42;
EXPECT_EQ(*v, 42);
EXPECT_EQ(v.GetPointer(), &*v);
*v = 0;
EXPECT_EQ(*v, 0);
}
struct NonMovable {
explicit NonMovable(int i) : i(i) {}
NonMovable(NonMovable&&) = delete;
auto operator=(NonMovable&&) -> NonMovable& = delete;
int i;
};
TEST(IndirectValueTest, Create) {
IndirectValue<NonMovable> v =
MakeIndirectValue([] { return NonMovable(42); });
EXPECT_EQ(v->i, 42);
}
auto GetIntReference() -> const int& {
static int i = 42;
return i;
}
TEST(IndirectValueTest, CreateWithDecay) {
auto v = MakeIndirectValue(GetIntReference);
EXPECT_TRUE((std::is_same_v<decltype(v), IndirectValue<int>>));
EXPECT_EQ(*v, 42);
}
// Test double which presents a value-like interface, but tracks which special
// member function (if any) caused it to reach its present value.
struct TestValue {
TestValue() : state("default constructed") {}
TestValue(const TestValue& /*rhs*/) : state("copy constructed") {}
TestValue(TestValue&& other) noexcept : state("move constructed") {
other.state = "move constructed from";
}
auto operator=(const TestValue& /*unused*/) noexcept -> TestValue& {
state = "copy assigned";
return *this;
}
auto operator=(TestValue&& other) noexcept -> TestValue& {
state = "move assigned";
other.state = "move assigned from";
return *this;
}
std::string state;
};
TEST(IndirectValueTest, ConstArrow) {
const IndirectValue<TestValue> v;
EXPECT_EQ(v->state, "default constructed");
}
TEST(IndirectValueTest, MutableArrow) {
IndirectValue<TestValue> v;
EXPECT_EQ(v->state, "default constructed");
v->state = "explicitly set";
EXPECT_EQ(v->state, "explicitly set");
}
TEST(IndirectValueTest, CopyConstruct) {
IndirectValue<TestValue> v1;
// NOLINTNEXTLINE(performance-unnecessary-copy-initialization)
auto v2 = v1;
EXPECT_EQ(v1->state, "default constructed");
EXPECT_EQ(v2->state, "copy constructed");
}
TEST(IndirectValueTest, CopyAssign) {
IndirectValue<TestValue> v1;
IndirectValue<TestValue> v2;
v2 = v1;
EXPECT_EQ(v1->state, "default constructed");
EXPECT_EQ(v2->state, "copy assigned");
}
TEST(IndirectValueTest, MoveConstruct) {
IndirectValue<TestValue> v1;
auto v2 = std::move(v1);
// While not entirely safe, the `v1->state` access tests move behavior.
// NOLINTNEXTLINE(bugprone-use-after-move)
EXPECT_EQ(v1->state, "move constructed from");
EXPECT_EQ(v2->state, "move constructed");
}
TEST(IndirectValueTest, MoveAssign) {
IndirectValue<TestValue> v1;
IndirectValue<TestValue> v2;
v2 = std::move(v1);
// While not entirely safe, the `v1->state` access tests move behavior.
// NOLINTNEXTLINE(bugprone-use-after-move)
EXPECT_EQ(v1->state, "move assigned from");
EXPECT_EQ(v2->state, "move assigned");
}
TEST(IndirectValueTest, IncompleteType) {
struct S {
std::optional<IndirectValue<S>> v;
};
S s = {.v = S{}};
}
} // namespace
} // namespace Carbon