summaryrefslogtreecommitdiff
path: root/absl/container/fixed_array_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'absl/container/fixed_array_test.cc')
-rw-r--r--absl/container/fixed_array_test.cc119
1 files changed, 38 insertions, 81 deletions
diff --git a/absl/container/fixed_array_test.cc b/absl/container/fixed_array_test.cc
index c960fe51..49598e7a 100644
--- a/absl/container/fixed_array_test.cc
+++ b/absl/container/fixed_array_test.cc
@@ -27,7 +27,10 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/base/config.h"
#include "absl/base/internal/exception_testing.h"
+#include "absl/base/options.h"
+#include "absl/container/internal/counting_allocator.h"
#include "absl/hash/hash_testing.h"
#include "absl/memory/memory.h"
@@ -188,6 +191,21 @@ TEST(FixedArrayTest, AtThrows) {
"failed bounds check");
}
+TEST(FixedArrayTest, Hardened) {
+#if !defined(NDEBUG) || ABSL_OPTION_HARDENED
+ absl::FixedArray<int> a = {1, 2, 3};
+ EXPECT_EQ(a[2], 3);
+ EXPECT_DEATH_IF_SUPPORTED(a[3], "");
+ EXPECT_DEATH_IF_SUPPORTED(a[-1], "");
+
+ absl::FixedArray<int> empty(0);
+ EXPECT_DEATH_IF_SUPPORTED(empty[0], "");
+ EXPECT_DEATH_IF_SUPPORTED(empty[-1], "");
+ EXPECT_DEATH_IF_SUPPORTED(empty.front(), "");
+ EXPECT_DEATH_IF_SUPPORTED(empty.back(), "");
+#endif
+}
+
TEST(FixedArrayRelationalsTest, EqualArrays) {
for (int i = 0; i < 10; ++i) {
absl::FixedArray<int, 5> a1(i);
@@ -622,70 +640,9 @@ TEST(FixedArrayTest, DefaultCtorDoesNotValueInit) {
}
#endif // __GNUC__
-// This is a stateful allocator, but the state lives outside of the
-// allocator (in whatever test is using the allocator). This is odd
-// but helps in tests where the allocator is propagated into nested
-// containers - that chain of allocators uses the same state and is
-// thus easier to query for aggregate allocation information.
-template <typename T>
-class CountingAllocator : public std::allocator<T> {
- public:
- using Alloc = std::allocator<T>;
- using pointer = typename Alloc::pointer;
- using size_type = typename Alloc::size_type;
-
- CountingAllocator() : bytes_used_(nullptr), instance_count_(nullptr) {}
- explicit CountingAllocator(int64_t* b)
- : bytes_used_(b), instance_count_(nullptr) {}
- CountingAllocator(int64_t* b, int64_t* a)
- : bytes_used_(b), instance_count_(a) {}
-
- template <typename U>
- explicit CountingAllocator(const CountingAllocator<U>& x)
- : Alloc(x),
- bytes_used_(x.bytes_used_),
- instance_count_(x.instance_count_) {}
-
- pointer allocate(size_type n, const void* const hint = nullptr) {
- assert(bytes_used_ != nullptr);
- *bytes_used_ += n * sizeof(T);
- return Alloc::allocate(n, hint);
- }
-
- void deallocate(pointer p, size_type n) {
- Alloc::deallocate(p, n);
- assert(bytes_used_ != nullptr);
- *bytes_used_ -= n * sizeof(T);
- }
-
- template <typename... Args>
- void construct(pointer p, Args&&... args) {
- Alloc::construct(p, absl::forward<Args>(args)...);
- if (instance_count_) {
- *instance_count_ += 1;
- }
- }
-
- void destroy(pointer p) {
- Alloc::destroy(p);
- if (instance_count_) {
- *instance_count_ -= 1;
- }
- }
-
- template <typename U>
- class rebind {
- public:
- using other = CountingAllocator<U>;
- };
-
- int64_t* bytes_used_;
- int64_t* instance_count_;
-};
-
TEST(AllocatorSupportTest, CountInlineAllocations) {
constexpr size_t inlined_size = 4;
- using Alloc = CountingAllocator<int>;
+ using Alloc = absl::container_internal::CountingAllocator<int>;
using AllocFxdArr = absl::FixedArray<int, inlined_size, Alloc>;
int64_t allocated = 0;
@@ -706,7 +663,7 @@ TEST(AllocatorSupportTest, CountInlineAllocations) {
TEST(AllocatorSupportTest, CountOutoflineAllocations) {
constexpr size_t inlined_size = 4;
- using Alloc = CountingAllocator<int>;
+ using Alloc = absl::container_internal::CountingAllocator<int>;
using AllocFxdArr = absl::FixedArray<int, inlined_size, Alloc>;
int64_t allocated = 0;
@@ -727,7 +684,7 @@ TEST(AllocatorSupportTest, CountOutoflineAllocations) {
TEST(AllocatorSupportTest, CountCopyInlineAllocations) {
constexpr size_t inlined_size = 4;
- using Alloc = CountingAllocator<int>;
+ using Alloc = absl::container_internal::CountingAllocator<int>;
using AllocFxdArr = absl::FixedArray<int, inlined_size, Alloc>;
int64_t allocated1 = 0;
@@ -755,7 +712,7 @@ TEST(AllocatorSupportTest, CountCopyInlineAllocations) {
TEST(AllocatorSupportTest, CountCopyOutoflineAllocations) {
constexpr size_t inlined_size = 4;
- using Alloc = CountingAllocator<int>;
+ using Alloc = absl::container_internal::CountingAllocator<int>;
using AllocFxdArr = absl::FixedArray<int, inlined_size, Alloc>;
int64_t allocated1 = 0;
@@ -787,7 +744,7 @@ TEST(AllocatorSupportTest, SizeValAllocConstructor) {
using testing::SizeIs;
constexpr size_t inlined_size = 4;
- using Alloc = CountingAllocator<int>;
+ using Alloc = absl::container_internal::CountingAllocator<int>;
using AllocFxdArr = absl::FixedArray<int, inlined_size, Alloc>;
{
@@ -811,16 +768,16 @@ TEST(AllocatorSupportTest, SizeValAllocConstructor) {
}
}
-#ifdef ADDRESS_SANITIZER
+#ifdef ABSL_HAVE_ADDRESS_SANITIZER
TEST(FixedArrayTest, AddressSanitizerAnnotations1) {
absl::FixedArray<int, 32> a(10);
int* raw = a.data();
raw[0] = 0;
raw[9] = 0;
- EXPECT_DEATH(raw[-2] = 0, "container-overflow");
- EXPECT_DEATH(raw[-1] = 0, "container-overflow");
- EXPECT_DEATH(raw[10] = 0, "container-overflow");
- EXPECT_DEATH(raw[31] = 0, "container-overflow");
+ EXPECT_DEATH_IF_SUPPORTED(raw[-2] = 0, "container-overflow");
+ EXPECT_DEATH_IF_SUPPORTED(raw[-1] = 0, "container-overflow");
+ EXPECT_DEATH_IF_SUPPORTED(raw[10] = 0, "container-overflow");
+ EXPECT_DEATH_IF_SUPPORTED(raw[31] = 0, "container-overflow");
}
TEST(FixedArrayTest, AddressSanitizerAnnotations2) {
@@ -828,10 +785,10 @@ TEST(FixedArrayTest, AddressSanitizerAnnotations2) {
char* raw = a.data();
raw[0] = 0;
raw[11] = 0;
- EXPECT_DEATH(raw[-7] = 0, "container-overflow");
- EXPECT_DEATH(raw[-1] = 0, "container-overflow");
- EXPECT_DEATH(raw[12] = 0, "container-overflow");
- EXPECT_DEATH(raw[17] = 0, "container-overflow");
+ EXPECT_DEATH_IF_SUPPORTED(raw[-7] = 0, "container-overflow");
+ EXPECT_DEATH_IF_SUPPORTED(raw[-1] = 0, "container-overflow");
+ EXPECT_DEATH_IF_SUPPORTED(raw[12] = 0, "container-overflow");
+ EXPECT_DEATH_IF_SUPPORTED(raw[17] = 0, "container-overflow");
}
TEST(FixedArrayTest, AddressSanitizerAnnotations3) {
@@ -839,8 +796,8 @@ TEST(FixedArrayTest, AddressSanitizerAnnotations3) {
uint64_t* raw = a.data();
raw[0] = 0;
raw[19] = 0;
- EXPECT_DEATH(raw[-1] = 0, "container-overflow");
- EXPECT_DEATH(raw[20] = 0, "container-overflow");
+ EXPECT_DEATH_IF_SUPPORTED(raw[-1] = 0, "container-overflow");
+ EXPECT_DEATH_IF_SUPPORTED(raw[20] = 0, "container-overflow");
}
TEST(FixedArrayTest, AddressSanitizerAnnotations4) {
@@ -852,13 +809,13 @@ TEST(FixedArrayTest, AddressSanitizerAnnotations4) {
// there is only a 8-byte red zone before the container range, so we only
// access the last 4 bytes of the struct to make sure it stays within the red
// zone.
- EXPECT_DEATH(raw[-1].z_ = 0, "container-overflow");
- EXPECT_DEATH(raw[10] = ThreeInts(), "container-overflow");
+ EXPECT_DEATH_IF_SUPPORTED(raw[-1].z_ = 0, "container-overflow");
+ EXPECT_DEATH_IF_SUPPORTED(raw[10] = ThreeInts(), "container-overflow");
// The actual size of storage is kDefaultBytes=256, 21*12 = 252,
// so reading raw[21] should still trigger the correct warning.
- EXPECT_DEATH(raw[21] = ThreeInts(), "container-overflow");
+ EXPECT_DEATH_IF_SUPPORTED(raw[21] = ThreeInts(), "container-overflow");
}
-#endif // ADDRESS_SANITIZER
+#endif // ABSL_HAVE_ADDRESS_SANITIZER
TEST(FixedArrayTest, AbslHashValueWorks) {
using V = absl::FixedArray<int>;