diff options
Diffstat (limited to 'absl/container')
-rw-r--r-- | absl/container/BUILD.bazel | 2 | ||||
-rw-r--r-- | absl/container/CMakeLists.txt | 2 | ||||
-rw-r--r-- | absl/container/fixed_array.h | 24 | ||||
-rw-r--r-- | absl/container/fixed_array_test.cc | 16 | ||||
-rw-r--r-- | absl/container/inlined_vector.h | 49 | ||||
-rw-r--r-- | absl/container/inlined_vector_test.cc | 11 |
6 files changed, 70 insertions, 34 deletions
diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index 709856414a0e..c7f7b0d9f4c0 100644 --- a/absl/container/BUILD.bazel +++ b/absl/container/BUILD.bazel @@ -74,6 +74,7 @@ cc_test( linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":fixed_array", + "//absl/base:config", "//absl/base:exception_testing", "//absl/hash:hash_testing", "//absl/memory", @@ -153,6 +154,7 @@ cc_test( ":counting_allocator", ":inlined_vector", ":test_instance_tracker", + "//absl/base:config", "//absl/base:core_headers", "//absl/base:exception_testing", "//absl/base:raw_logging_internal", diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt index 99a8e9c0a5a1..a732fe8273ac 100644 --- a/absl/container/CMakeLists.txt +++ b/absl/container/CMakeLists.txt @@ -147,6 +147,7 @@ absl_cc_test( ${ABSL_TEST_COPTS} DEPS absl::fixed_array + absl::config absl::exception_testing absl::hash_testing absl::memory @@ -221,6 +222,7 @@ absl_cc_test( absl::counting_allocator absl::inlined_vector absl::test_instance_tracker + absl::config absl::core_headers absl::exception_testing absl::hash_testing diff --git a/absl/container/fixed_array.h b/absl/container/fixed_array.h index a9ce99bafd32..796dd629a6bf 100644 --- a/absl/container/fixed_array.h +++ b/absl/container/fixed_array.h @@ -217,7 +217,7 @@ class FixedArray { // Returns a reference the ith element of the fixed array. // REQUIRES: 0 <= i < size() reference operator[](size_type i) { - assert(i < size()); + ABSL_HARDENING_ASSERT(i < size()); return data()[i]; } @@ -225,7 +225,7 @@ class FixedArray { // ith element of the fixed array. // REQUIRES: 0 <= i < size() const_reference operator[](size_type i) const { - assert(i < size()); + ABSL_HARDENING_ASSERT(i < size()); return data()[i]; } @@ -252,20 +252,32 @@ class FixedArray { // FixedArray::front() // // Returns a reference to the first element of the fixed array. - reference front() { return *begin(); } + reference front() { + ABSL_HARDENING_ASSERT(!empty()); + return data()[0]; + } // Overload of FixedArray::front() to return a reference to the first element // of a fixed array of const values. - const_reference front() const { return *begin(); } + const_reference front() const { + ABSL_HARDENING_ASSERT(!empty()); + return data()[0]; + } // FixedArray::back() // // Returns a reference to the last element of the fixed array. - reference back() { return *(end() - 1); } + reference back() { + ABSL_HARDENING_ASSERT(!empty()); + return data()[size() - 1]; + } // Overload of FixedArray::back() to return a reference to the last element // of a fixed array of const values. - const_reference back() const { return *(end() - 1); } + const_reference back() const { + ABSL_HARDENING_ASSERT(!empty()); + return data()[size() - 1]; + } // FixedArray::begin() // diff --git a/absl/container/fixed_array_test.cc b/absl/container/fixed_array_test.cc index c960fe51c100..9b1c224f8608 100644 --- a/absl/container/fixed_array_test.cc +++ b/absl/container/fixed_array_test.cc @@ -28,6 +28,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" #include "absl/base/internal/exception_testing.h" +#include "absl/base/options.h" #include "absl/hash/hash_testing.h" #include "absl/memory/memory.h" @@ -188,6 +189,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); diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h index 2388d471dcc8..5f6f6154bf64 100644 --- a/absl/container/inlined_vector.h +++ b/absl/container/inlined_vector.h @@ -48,6 +48,7 @@ #include "absl/algorithm/algorithm.h" #include "absl/base/internal/throw_delegate.h" +#include "absl/base/macros.h" #include "absl/base/optimization.h" #include "absl/base/port.h" #include "absl/container/internal/inlined_vector.h" @@ -307,16 +308,14 @@ class InlinedVector { // // Returns a `reference` to the `i`th element of the inlined vector. reference operator[](size_type i) { - assert(i < size()); - + ABSL_HARDENING_ASSERT(i < size()); return data()[i]; } // Overload of `InlinedVector::operator[](...)` that returns a // `const_reference` to the `i`th element of the inlined vector. const_reference operator[](size_type i) const { - assert(i < size()); - + ABSL_HARDENING_ASSERT(i < size()); return data()[i]; } @@ -331,7 +330,6 @@ class InlinedVector { base_internal::ThrowStdOutOfRange( "`InlinedVector::at(size_type)` failed bounds check"); } - return data()[i]; } @@ -345,7 +343,6 @@ class InlinedVector { base_internal::ThrowStdOutOfRange( "`InlinedVector::at(size_type) const` failed bounds check"); } - return data()[i]; } @@ -353,16 +350,14 @@ class InlinedVector { // // Returns a `reference` to the first element of the inlined vector. reference front() { - assert(!empty()); - + ABSL_HARDENING_ASSERT(!empty()); return at(0); } // Overload of `InlinedVector::front()` that returns a `const_reference` to // the first element of the inlined vector. const_reference front() const { - assert(!empty()); - + ABSL_HARDENING_ASSERT(!empty()); return at(0); } @@ -370,16 +365,14 @@ class InlinedVector { // // Returns a `reference` to the last element of the inlined vector. reference back() { - assert(!empty()); - + ABSL_HARDENING_ASSERT(!empty()); return at(size() - 1); } // Overload of `InlinedVector::back()` that returns a `const_reference` to the // last element of the inlined vector. const_reference back() const { - assert(!empty()); - + ABSL_HARDENING_ASSERT(!empty()); return at(size() - 1); } @@ -573,8 +566,8 @@ class InlinedVector { // of `v` starting at `pos`, returning an `iterator` pointing to the first of // the newly inserted elements. iterator insert(const_iterator pos, size_type n, const_reference v) { - assert(pos >= begin()); - assert(pos <= end()); + ABSL_HARDENING_ASSERT(pos >= begin()); + ABSL_HARDENING_ASSERT(pos <= end()); if (ABSL_PREDICT_TRUE(n != 0)) { value_type dealias = v; @@ -600,8 +593,8 @@ class InlinedVector { EnableIfAtLeastForwardIterator<ForwardIterator>* = nullptr> iterator insert(const_iterator pos, ForwardIterator first, ForwardIterator last) { - assert(pos >= begin()); - assert(pos <= end()); + ABSL_HARDENING_ASSERT(pos >= begin()); + ABSL_HARDENING_ASSERT(pos <= end()); if (ABSL_PREDICT_TRUE(first != last)) { return storage_.Insert(pos, IteratorValueAdapter<ForwardIterator>(first), @@ -619,8 +612,8 @@ class InlinedVector { template <typename InputIterator, DisableIfAtLeastForwardIterator<InputIterator>* = nullptr> iterator insert(const_iterator pos, InputIterator first, InputIterator last) { - assert(pos >= begin()); - assert(pos <= end()); + ABSL_HARDENING_ASSERT(pos >= begin()); + ABSL_HARDENING_ASSERT(pos <= end()); size_type index = std::distance(cbegin(), pos); for (size_type i = index; first != last; ++i, static_cast<void>(++first)) { @@ -636,8 +629,8 @@ class InlinedVector { // `pos`, returning an `iterator` pointing to the newly emplaced element. template <typename... Args> iterator emplace(const_iterator pos, Args&&... args) { - assert(pos >= begin()); - assert(pos <= end()); + ABSL_HARDENING_ASSERT(pos >= begin()); + ABSL_HARDENING_ASSERT(pos <= end()); value_type dealias(std::forward<Args>(args)...); return storage_.Insert(pos, @@ -670,7 +663,7 @@ class InlinedVector { // // Destroys the element at `back()`, reducing the size by `1`. void pop_back() noexcept { - assert(!empty()); + ABSL_HARDENING_ASSERT(!empty()); AllocatorTraits::destroy(*storage_.GetAllocPtr(), data() + (size() - 1)); storage_.SubtractSize(1); @@ -683,8 +676,8 @@ class InlinedVector { // // NOTE: may return `end()`, which is not dereferencable. iterator erase(const_iterator pos) { - assert(pos >= begin()); - assert(pos < end()); + ABSL_HARDENING_ASSERT(pos >= begin()); + ABSL_HARDENING_ASSERT(pos < end()); return storage_.Erase(pos, pos + 1); } @@ -695,9 +688,9 @@ class InlinedVector { // // NOTE: may return `end()`, which is not dereferencable. iterator erase(const_iterator from, const_iterator to) { - assert(from >= begin()); - assert(from <= to); - assert(to <= end()); + ABSL_HARDENING_ASSERT(from >= begin()); + ABSL_HARDENING_ASSERT(from <= to); + ABSL_HARDENING_ASSERT(to <= end()); if (ABSL_PREDICT_TRUE(from != to)) { return storage_.Erase(from, to); diff --git a/absl/container/inlined_vector_test.cc b/absl/container/inlined_vector_test.cc index 5965eac77d03..415c60d9f1af 100644 --- a/absl/container/inlined_vector_test.cc +++ b/absl/container/inlined_vector_test.cc @@ -30,6 +30,7 @@ #include "absl/base/internal/exception_testing.h" #include "absl/base/internal/raw_logging.h" #include "absl/base/macros.h" +#include "absl/base/options.h" #include "absl/container/internal/counting_allocator.h" #include "absl/container/internal/test_instance_tracker.h" #include "absl/hash/hash_testing.h" @@ -247,6 +248,16 @@ TEST(IntVec, Erase) { } } +TEST(IntVec, Hardened) { + IntVec v; + Fill(&v, 10); + EXPECT_EQ(v[9], 9); +#if !defined(NDEBUG) || ABSL_OPTION_HARDENED + EXPECT_DEATH_IF_SUPPORTED(v[10], ""); + EXPECT_DEATH_IF_SUPPORTED(v[-1], ""); +#endif +} + // At the end of this test loop, the elements between [erase_begin, erase_end) // should have reference counts == 0, and all others elements should have // reference counts == 1. |