Skip to content

Commit

Permalink
[libc++] Fix bug in tests for std::atomic_ref<T*> increment and decre…
Browse files Browse the repository at this point in the history
…ment operators (#122271)

The implementation is fine and has the proper increment/decrement
operators defined, but the tests were wrong:
- a typo (`T` instead of `std::atomic_ref<T>`) when ensuring that increment/decrement
  operators are not defined in the primary template and specialization for floating point
  types, and
- the specialization for pointer types was miscategorized.
  • Loading branch information
dalg24 authored Jan 10, 2025
1 parent 9248428 commit 19557a4
Showing 1 changed file with 68 additions and 33 deletions.
101 changes: 68 additions & 33 deletions libcxx/test/std/atomics/atomics.ref/increment_decrement.pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,43 +42,78 @@ constexpr bool does_not_have_increment_nor_decrement_operators() {

template <typename T>
struct TestDoesNotHaveIncrementDecrement {
void operator()() const { static_assert(does_not_have_increment_nor_decrement_operators<T>()); }
void operator()() const { static_assert(does_not_have_increment_nor_decrement_operators<std::atomic_ref<T>>()); }
};

template <typename T>
struct TestIncrementDecrement {
void operator()() const {
static_assert(std::is_integral_v<T>);

T x(T(1));
std::atomic_ref<T> const a(x);

{
std::same_as<T> decltype(auto) y = ++a;
assert(y == T(2));
assert(x == T(2));
ASSERT_NOEXCEPT(++a);
}

{
std::same_as<T> decltype(auto) y = --a;
assert(y == T(1));
assert(x == T(1));
ASSERT_NOEXCEPT(--a);
}

{
std::same_as<T> decltype(auto) y = a++;
assert(y == T(1));
assert(x == T(2));
ASSERT_NOEXCEPT(a++);
}

{
std::same_as<T> decltype(auto) y = a--;
assert(y == T(2));
assert(x == T(1));
ASSERT_NOEXCEPT(a--);
if constexpr (std::is_integral_v<T>) {
T x(T(1));
std::atomic_ref<T> const a(x);

{
std::same_as<T> decltype(auto) y = ++a;
assert(y == T(2));
assert(x == T(2));
ASSERT_NOEXCEPT(++a);
}

{
std::same_as<T> decltype(auto) y = --a;
assert(y == T(1));
assert(x == T(1));
ASSERT_NOEXCEPT(--a);
}

{
std::same_as<T> decltype(auto) y = a++;
assert(y == T(1));
assert(x == T(2));
ASSERT_NOEXCEPT(a++);
}

{
std::same_as<T> decltype(auto) y = a--;
assert(y == T(2));
assert(x == T(1));
ASSERT_NOEXCEPT(a--);
}
} else if constexpr (std::is_pointer_v<T>) {
using U = std::remove_pointer_t<T>;
U t[9] = {};
T p{&t[1]};
std::atomic_ref<T> const a(p);

{
std::same_as<T> decltype(auto) y = ++a;
assert(y == &t[2]);
assert(p == &t[2]);
ASSERT_NOEXCEPT(++a);
}

{
std::same_as<T> decltype(auto) y = --a;
assert(y == &t[1]);
assert(p == &t[1]);
ASSERT_NOEXCEPT(--a);
}

{
std::same_as<T> decltype(auto) y = a++;
assert(y == &t[1]);
assert(p == &t[2]);
ASSERT_NOEXCEPT(a++);
}

{
std::same_as<T> decltype(auto) y = a--;
assert(y == &t[2]);
assert(p == &t[1]);
ASSERT_NOEXCEPT(a--);
}
} else {
static_assert(std::is_void_v<T>);
}
}
};
Expand All @@ -88,7 +123,7 @@ int main(int, char**) {

TestEachFloatingPointType<TestDoesNotHaveIncrementDecrement>()();

TestEachPointerType<TestDoesNotHaveIncrementDecrement>()();
TestEachPointerType<TestIncrementDecrement>()();

TestDoesNotHaveIncrementDecrement<bool>()();
TestDoesNotHaveIncrementDecrement<UserAtomicType>()();
Expand Down

0 comments on commit 19557a4

Please sign in to comment.