diff --git a/CMakeLists.txt b/CMakeLists.txt index fda9e01bbb..ce8f5878d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. See the AUTHORS file for names of contributors. -cmake_minimum_required(VERSION 3.9) +cmake_minimum_required(VERSION 3.22) # Keep the version below in sync with the one in db.h project(leveldb VERSION 1.23.0 LANGUAGES C CXX) @@ -16,8 +16,8 @@ endif(NOT CMAKE_C_STANDARD) # C++ standard can be overridden when this is used as a sub-project. if(NOT CMAKE_CXX_STANDARD) - # This project requires C++11. - set(CMAKE_CXX_STANDARD 11) + # This project requires C++17. + set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) endif(NOT CMAKE_CXX_STANDARD) diff --git a/db/db_impl.cc b/db/db_impl.cc index f96d245583..ce4ef8276a 100644 --- a/db/db_impl.cc +++ b/db/db_impl.cc @@ -646,7 +646,8 @@ Status DBImpl::TEST_CompactMemTable() { if (s.ok()) { // Wait until the compaction completes MutexLock l(&mutex_); - while (imm_ != nullptr && bg_error_.ok()) { + while (imm_ != nullptr && bg_error_.ok() && + !shutting_down_.load(std::memory_order_acquire)) { background_work_finished_signal_.Wait(); } if (imm_ != nullptr) { diff --git a/db/memtable.cc b/db/memtable.cc index 4f09340e0e..33a99288c8 100644 --- a/db/memtable.cc +++ b/db/memtable.cc @@ -12,7 +12,7 @@ namespace leveldb { static Slice GetLengthPrefixedSlice(const char* data) { - uint32_t len; + uint32_t len = 0u; const char* p = data; p = GetVarint32Ptr(p, p + 5, &len); // +5: we assume "p" is not corrupted return Slice(p, len); @@ -114,8 +114,11 @@ bool MemTable::Get(const LookupKey& key, std::string* value, Status* s) { // sequence number since the Seek() call above should have skipped // all entries with overly large sequence numbers. const char* entry = iter.key(); - uint32_t key_length; + uint32_t key_length = 0u; const char* key_ptr = GetVarint32Ptr(entry, entry + 5, &key_length); + if (!key_ptr) { + return false; + } if (comparator_.comparator.user_comparator()->Compare( Slice(key_ptr, key_length - 8), key.user_key()) == 0) { // Correct user key diff --git a/include/leveldb/slice.h b/include/leveldb/slice.h index 37cb82178d..e97223a743 100644 --- a/include/leveldb/slice.h +++ b/include/leveldb/slice.h @@ -51,6 +51,9 @@ class LEVELDB_EXPORT Slice { // Return true iff the length of the referenced data is zero bool empty() const { return size_ == 0; } + const char* begin() const { return data(); } + const char* end() const { return data() + size(); } + // Return the ith byte in the referenced data. // REQUIRES: n < size() char operator[](size_t n) const { diff --git a/third_party/benchmark b/third_party/benchmark index f7547e29cc..1a54956777 160000 --- a/third_party/benchmark +++ b/third_party/benchmark @@ -1 +1 @@ -Subproject commit f7547e29ccaed7b64ef4f7495ecfff1c9f6f3d03 +Subproject commit 1a54956777ba672764db09a51960056ea042af7e diff --git a/third_party/googletest b/third_party/googletest index 662fe38e44..a35bc7693c 160000 --- a/third_party/googletest +++ b/third_party/googletest @@ -1 +1 @@ -Subproject commit 662fe38e44900c007eccb65a5d2ea19df7bd520e +Subproject commit a35bc7693c117a048152beeb34f6aac354b9423f diff --git a/util/env_posix.cc b/util/env_posix.cc index ffd06c4031..c2490322e5 100644 --- a/util/env_posix.cc +++ b/util/env_posix.cc @@ -874,9 +874,13 @@ class SingletonEnv { #endif // !defined(NDEBUG) static_assert(sizeof(env_storage_) >= sizeof(EnvType), "env_storage_ will not fit the Env"); - static_assert(alignof(decltype(env_storage_)) >= alignof(EnvType), + static_assert(std::is_standard_layout_v>); + static_assert( + offsetof(SingletonEnv, env_storage_) % alignof(EnvType) == 0, + "env_storage_ does not meet the Env's alignment needs"); + static_assert(alignof(SingletonEnv) % alignof(EnvType) == 0, "env_storage_ does not meet the Env's alignment needs"); - new (&env_storage_) EnvType(); + new (env_storage_) EnvType(); } ~SingletonEnv() = default; @@ -892,8 +896,7 @@ class SingletonEnv { } private: - typename std::aligned_storage::type - env_storage_; + alignas(EnvType) char env_storage_[sizeof(EnvType)]; #if !defined(NDEBUG) static std::atomic env_initialized_; #endif // !defined(NDEBUG) diff --git a/util/env_windows.cc b/util/env_windows.cc index 1c74b02a7f..ae5149a505 100644 --- a/util/env_windows.cc +++ b/util/env_windows.cc @@ -769,9 +769,13 @@ class SingletonEnv { #endif // !defined(NDEBUG) static_assert(sizeof(env_storage_) >= sizeof(EnvType), "env_storage_ will not fit the Env"); - static_assert(alignof(decltype(env_storage_)) >= alignof(EnvType), + static_assert(std::is_standard_layout_v>); + static_assert( + offsetof(SingletonEnv, env_storage_) % alignof(EnvType) == 0, + "env_storage_ does not meet the Env's alignment needs"); + static_assert(alignof(SingletonEnv) % alignof(EnvType) == 0, "env_storage_ does not meet the Env's alignment needs"); - new (&env_storage_) EnvType(); + new (env_storage_) EnvType(); } ~SingletonEnv() = default; @@ -787,8 +791,7 @@ class SingletonEnv { } private: - typename std::aligned_storage::type - env_storage_; + alignas(EnvType) char env_storage_[sizeof(EnvType)]; #if !defined(NDEBUG) static std::atomic env_initialized_; #endif // !defined(NDEBUG) diff --git a/util/hash.cc b/util/hash.cc index 8122fa834d..fa252c72e1 100644 --- a/util/hash.cc +++ b/util/hash.cc @@ -27,7 +27,7 @@ uint32_t Hash(const char* data, size_t n, uint32_t seed) { uint32_t h = seed ^ (n * m); // Pick up four bytes at a time - while (data + 4 <= limit) { + while (limit - data >= 4) { uint32_t w = DecodeFixed32(data); data += 4; h += w; diff --git a/util/no_destructor.h b/util/no_destructor.h index a0d3b8703d..c28a107313 100644 --- a/util/no_destructor.h +++ b/util/no_destructor.h @@ -5,6 +5,7 @@ #ifndef STORAGE_LEVELDB_UTIL_NO_DESTRUCTOR_H_ #define STORAGE_LEVELDB_UTIL_NO_DESTRUCTOR_H_ +#include #include #include @@ -20,10 +21,14 @@ class NoDestructor { explicit NoDestructor(ConstructorArgTypes&&... constructor_args) { static_assert(sizeof(instance_storage_) >= sizeof(InstanceType), "instance_storage_ is not large enough to hold the instance"); + static_assert(std::is_standard_layout_v>); static_assert( - alignof(decltype(instance_storage_)) >= alignof(InstanceType), + offsetof(NoDestructor, instance_storage_) % alignof(InstanceType) == 0, "instance_storage_ does not meet the instance's alignment requirement"); - new (&instance_storage_) + static_assert( + alignof(NoDestructor) % alignof(InstanceType) == 0, + "instance_storage_ does not meet the instance's alignment requirement"); + new (instance_storage_) InstanceType(std::forward(constructor_args)...); } @@ -37,8 +42,7 @@ class NoDestructor { } private: - typename std::aligned_storage::type instance_storage_; + alignas(InstanceType) char instance_storage_[sizeof(InstanceType)]; }; } // namespace leveldb