diff --git a/CMake/AbseilDll.cmake b/CMake/AbseilDll.cmake index 96fb5c6..38d0936 100644 --- a/CMake/AbseilDll.cmake +++ b/CMake/AbseilDll.cmake
@@ -201,6 +201,7 @@ "log/initialize.cc" "log/initialize.h" "log/log.h" + "log/log_entry.cc" "log/log_entry.h" "log/log_sink.cc" "log/log_sink.h"
diff --git a/absl/base/attributes.h b/absl/base/attributes.h index d009f6d..33b2c28 100644 --- a/absl/base/attributes.h +++ b/absl/base/attributes.h
@@ -553,7 +553,7 @@ // // Prevents the compiler from complaining about variables that appear unused. // -// Deprecated: Use the standard C++17 `[[maybe_unused]` instead. +// Deprecated: Use the standard C++17 `[[maybe_unused]]` instead. // // Due to differences in positioning requirements between the old, compiler // specific __attribute__ syntax and the now standard `[[maybe_unused]]`, this
diff --git a/absl/base/config.h b/absl/base/config.h index f3cafbd..b1c5227 100644 --- a/absl/base/config.h +++ b/absl/base/config.h
@@ -237,6 +237,8 @@ #error ABSL_HAVE_TLS cannot be directly set #elif (defined(__linux__)) && (defined(__clang__) || defined(_GLIBCXX_HAVE_TLS)) #define ABSL_HAVE_TLS 1 +#elif defined(__INTEL_LLVM_COMPILER) +#define ABSL_HAVE_TLS 1 #endif // ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE
diff --git a/absl/base/internal/poison.cc b/absl/base/internal/poison.cc index b33d4c2..c639c96 100644 --- a/absl/base/internal/poison.cc +++ b/absl/base/internal/poison.cc
@@ -57,19 +57,20 @@ void* InitializePoisonedPointerInternal() { const size_t block_size = GetPageSize(); + void* data = nullptr; #if defined(ABSL_HAVE_ADDRESS_SANITIZER) - void* data = malloc(block_size); + data = malloc(block_size); ASAN_POISON_MEMORY_REGION(data, block_size); #elif defined(ABSL_HAVE_MEMORY_SANITIZER) - void* data = malloc(block_size); + data = malloc(block_size); __msan_poison(data, block_size); #elif defined(ABSL_HAVE_MMAP) - void* data = DirectMmap(nullptr, block_size, PROT_NONE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + data = DirectMmap(nullptr, block_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0); if (data == MAP_FAILED) return GetBadPointerInternal(); #elif defined(_WIN32) - void* data = VirtualAlloc(nullptr, block_size, MEM_RESERVE | MEM_COMMIT, - PAGE_NOACCESS); + data = VirtualAlloc(nullptr, block_size, MEM_RESERVE | MEM_COMMIT, + PAGE_NOACCESS); if (data == nullptr) return GetBadPointerInternal(); #else return GetBadPointerInternal();
diff --git a/absl/base/internal/spinlock.h b/absl/base/internal/spinlock.h index 16fe93e..ff2b087 100644 --- a/absl/base/internal/spinlock.h +++ b/absl/base/internal/spinlock.h
@@ -101,6 +101,7 @@ ABSL_TSAN_MUTEX_POST_LOCK(this, 0, 0); } + ABSL_DEPRECATE_AND_INLINE() inline void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION() { return lock(); } // Try to acquire this SpinLock without blocking and return true if the @@ -116,6 +117,7 @@ return res; } + ABSL_DEPRECATE_AND_INLINE() [[nodiscard]] inline bool TryLock() ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(true) { return try_lock(); } @@ -139,6 +141,7 @@ ABSL_TSAN_MUTEX_POST_UNLOCK(this, 0); } + ABSL_DEPRECATE_AND_INLINE() inline void Unlock() ABSL_UNLOCK_FUNCTION() { unlock(); } // Determine if the lock is held. When the lock is held by the invoking @@ -235,17 +238,23 @@ // the duration of a C++ scope. class ABSL_SCOPED_LOCKABLE [[nodiscard]] SpinLockHolder { public: - inline explicit SpinLockHolder(SpinLock* l) ABSL_EXCLUSIVE_LOCK_FUNCTION(l) + inline explicit SpinLockHolder( + SpinLock& l ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this)) + ABSL_EXCLUSIVE_LOCK_FUNCTION(l) : lock_(l) { - l->lock(); + l.lock(); } - inline ~SpinLockHolder() ABSL_UNLOCK_FUNCTION() { lock_->unlock(); } + ABSL_DEPRECATE_AND_INLINE() + inline explicit SpinLockHolder(SpinLock* l) ABSL_EXCLUSIVE_LOCK_FUNCTION(l) + : SpinLockHolder(*l) {} + + inline ~SpinLockHolder() ABSL_UNLOCK_FUNCTION() { lock_.unlock(); } SpinLockHolder(const SpinLockHolder&) = delete; SpinLockHolder& operator=(const SpinLockHolder&) = delete; private: - SpinLock* lock_; + SpinLock& lock_; }; // Register a hook for profiling support.
diff --git a/absl/base/internal/spinlock_benchmark.cc b/absl/base/internal/spinlock_benchmark.cc index 993cab6..c79f49f 100644 --- a/absl/base/internal/spinlock_benchmark.cc +++ b/absl/base/internal/spinlock_benchmark.cc
@@ -50,7 +50,7 @@ static absl::NoDestructor<absl::base_internal::SpinLock> spinlock( scheduling_mode); for (auto _ : state) { - absl::base_internal::SpinLockHolder holder(spinlock.get()); + absl::base_internal::SpinLockHolder holder(*spinlock.get()); } }
diff --git a/absl/base/internal/sysinfo_test.cc b/absl/base/internal/sysinfo_test.cc index c2b59aa..0fbd163 100644 --- a/absl/base/internal/sysinfo_test.cc +++ b/absl/base/internal/sysinfo_test.cc
@@ -59,7 +59,7 @@ threads.push_back(std::thread([&]() { pid_t id = GetTID(); { - MutexLock lock(&mutex); + MutexLock lock(mutex); ASSERT_TRUE(tids.find(id) == tids.end()); tids.insert(id); }
diff --git a/absl/base/internal/thread_identity_test.cc b/absl/base/internal/thread_identity_test.cc index 4052291..3ef2ffe 100644 --- a/absl/base/internal/thread_identity_test.cc +++ b/absl/base/internal/thread_identity_test.cc
@@ -58,7 +58,7 @@ PerThreadSynch::kAlignment); EXPECT_EQ(identity, identity->per_thread_synch.thread_identity()); - absl::base_internal::SpinLockHolder l(&map_lock); + absl::base_internal::SpinLockHolder l(map_lock); num_identities_reused++; } @@ -90,7 +90,7 @@ // We should have recycled ThreadIdentity objects above; while (external) // library threads allocating their own identities may preclude some // reuse, we should have sufficient repetitions to exclude this. - absl::base_internal::SpinLockHolder l(&map_lock); + absl::base_internal::SpinLockHolder l(map_lock); EXPECT_LT(kNumThreads, num_identities_reused); } @@ -112,7 +112,7 @@ threads.push_back(std::thread([&]() { for (int l = 0; l < kNumLockLoops; ++l) { for (int m = 0; m < kNumMutexes; ++m) { - MutexLock lock(&mutexes[m]); + MutexLock lock(mutexes[m]); } } }));
diff --git a/absl/base/spinlock_test_common.cc b/absl/base/spinlock_test_common.cc index 56b09ec..9c2feb3 100644 --- a/absl/base/spinlock_test_common.cc +++ b/absl/base/spinlock_test_common.cc
@@ -101,7 +101,7 @@ static void TestFunction(uint32_t thread_salt, SpinLock* spinlock) { for (int i = 0; i < kIters; i++) { - SpinLockHolder h(spinlock); + SpinLockHolder h(*spinlock); for (size_t j = 0; j < kArrayLength; j++) { const size_t index = (j + thread_salt) % kArrayLength; values[index] = Hash32(values[index], thread_salt); @@ -120,7 +120,7 @@ thread.join(); } - SpinLockHolder h(spinlock); + SpinLockHolder h(*spinlock); for (size_t i = 1; i < kArrayLength; i++) { EXPECT_EQ(values[0], values[i]); } @@ -132,12 +132,12 @@ TEST(SpinLock, StackNonCooperativeDisablesScheduling) { SpinLock spinlock(base_internal::SCHEDULE_KERNEL_ONLY); - SpinLockHolder l(&spinlock); + SpinLockHolder l(spinlock); EXPECT_FALSE(base_internal::SchedulingGuard::ReschedulingIsAllowed()); } TEST(SpinLock, StaticNonCooperativeDisablesScheduling) { - SpinLockHolder l(&static_noncooperative_spinlock); + SpinLockHolder l(static_noncooperative_spinlock); EXPECT_FALSE(base_internal::SchedulingGuard::ReschedulingIsAllowed()); } @@ -243,12 +243,12 @@ BlockingCounter* b) { locked->WaitForNotification(); // Wait for LockThenWait() to hold "s". b->DecrementCount(); - SpinLockHolder l(spinlock); + SpinLockHolder l(*spinlock); } static void LockThenWait(Notification* locked, SpinLock* spinlock, BlockingCounter* b) { - SpinLockHolder l(spinlock); + SpinLockHolder l(*spinlock); locked->Notify(); b->Wait(); }
diff --git a/absl/container/internal/hashtablez_sampler_test.cc b/absl/container/internal/hashtablez_sampler_test.cc index 0de1e29..ef80cb0 100644 --- a/absl/container/internal/hashtablez_sampler_test.cc +++ b/absl/container/internal/hashtablez_sampler_test.cc
@@ -90,7 +90,7 @@ const size_t test_value_size = 13; HashtablezInfo info; - absl::MutexLock l(&info.init_mu); + absl::MutexLock l(info.init_mu); info.PrepareForSampling(test_stride, test_element_size, /*key_size=*/test_key_size, /*value_size=*/test_value_size, @@ -148,7 +148,7 @@ TEST(HashtablezInfoTest, RecordStorageChanged) { HashtablezInfo info; - absl::MutexLock l(&info.init_mu); + absl::MutexLock l(info.init_mu); const int64_t test_stride = 21; const size_t test_element_size = 19; const size_t test_key_size = 17; @@ -168,7 +168,7 @@ TEST(HashtablezInfoTest, RecordInsert) { HashtablezInfo info; - absl::MutexLock l(&info.init_mu); + absl::MutexLock l(info.init_mu); const int64_t test_stride = 25; const size_t test_element_size = 23; const size_t test_key_size = 21; @@ -203,7 +203,7 @@ const size_t test_value_size = 25; HashtablezInfo info; - absl::MutexLock l(&info.init_mu); + absl::MutexLock l(info.init_mu); info.PrepareForSampling(test_stride, test_element_size, /*key_size=*/test_key_size, /*value_size=*/test_value_size, @@ -227,7 +227,7 @@ const size_t test_key_size = 29; const size_t test_value_size = 27; HashtablezInfo info; - absl::MutexLock l(&info.init_mu); + absl::MutexLock l(info.init_mu); info.PrepareForSampling(test_stride, test_element_size, /*key_size=*/test_key_size, /*value_size=*/test_value_size, @@ -259,7 +259,7 @@ TEST(HashtablezInfoTest, RecordReservation) { HashtablezInfo info; - absl::MutexLock l(&info.init_mu); + absl::MutexLock l(info.init_mu); const int64_t test_stride = 35; const size_t test_element_size = 33; const size_t test_key_size = 31;
diff --git a/absl/crc/internal/cpu_detect.cc b/absl/crc/internal/cpu_detect.cc index c59f773..a697601 100644 --- a/absl/crc/internal/cpu_detect.cc +++ b/absl/crc/internal/cpu_detect.cc
@@ -145,6 +145,14 @@ } case 0x5e: // Skylake (client) return CpuType::kIntelSkylake; + case 0x6a: // Ice Lake + return CpuType::kIntelIcelake; + case 0x8f: // Sapphire Rapids + return CpuType::kIntelSapphirerapids; + case 0xcf: // Emerald Rapids + return CpuType::kIntelEmeraldrapids; + case 0xad: // Granite Rapids + return CpuType::kIntelGraniterapidsap; default: return CpuType::kUnknown; } @@ -210,6 +218,14 @@ return CpuType::kUnknown; } break; + case 0x1A: + switch (model_num) { + case 0x2: + return CpuType::kAmdTurin; + default: + return CpuType::kUnknown; + } + break; default: return CpuType::kUnknown; } @@ -259,6 +275,7 @@ case 0xd40: return CpuType::kArmNeoverseV1; case 0xd49: return CpuType::kArmNeoverseN2; case 0xd4f: return CpuType::kArmNeoverseV2; + case 0xd8e: return CpuType::kArmNeoverseN3; default: return CpuType::kUnknown; }
diff --git a/absl/crc/internal/cpu_detect.h b/absl/crc/internal/cpu_detect.h index 01e1959..e76a802 100644 --- a/absl/crc/internal/cpu_detect.h +++ b/absl/crc/internal/cpu_detect.h
@@ -30,10 +30,15 @@ kAmdNaples, kAmdMilan, kAmdGenoa, + kAmdTurin, kAmdRyzenV3000, kIntelCascadelakeXeon, kIntelSkylakeXeon, kIntelBroadwell, + kIntelIcelake, + kIntelSapphirerapids, + kIntelEmeraldrapids, + kIntelGraniterapidsap, kIntelSkylake, kIntelIvybridge, kIntelSandybridge, @@ -42,7 +47,8 @@ kArmNeoverseV1, kAmpereSiryn, kArmNeoverseN2, - kArmNeoverseV2 + kArmNeoverseV2, + kArmNeoverseN3, }; // Returns the type of host CPU this code is running on. Returns kUnknown if
diff --git a/absl/crc/internal/crc_x86_arm_combined.cc b/absl/crc/internal/crc_x86_arm_combined.cc index 03cf348..30cf6a1 100644 --- a/absl/crc/internal/crc_x86_arm_combined.cc +++ b/absl/crc/internal/crc_x86_arm_combined.cc
@@ -350,7 +350,8 @@ class CRC32AcceleratedX86ARMCombinedMultipleStreams : public CRC32AcceleratedX86ARMCombinedMultipleStreamsBase { ABSL_ATTRIBUTE_HOT - void Extend(uint32_t* crc, const void* bytes, size_t length) const override { + void Extend(uint32_t* crc, const void* bytes, + const size_t length) const override { static_assert(num_crc_streams >= 1 && num_crc_streams <= kMaxStreams, "Invalid number of crc streams"); static_assert(num_pclmul_streams >= 0 && num_pclmul_streams <= kMaxStreams, @@ -360,47 +361,15 @@ uint32_t l = *crc; uint64_t l64; - // We have dedicated instruction for 1,2,4 and 8 bytes. - if (length & 8) { - ABSL_INTERNAL_STEP8(l, p); - length &= ~size_t{8}; - } - if (length & 4) { - ABSL_INTERNAL_STEP4(l, p); - length &= ~size_t{4}; - } - if (length & 2) { - ABSL_INTERNAL_STEP2(l, p); - length &= ~size_t{2}; - } - if (length & 1) { - ABSL_INTERNAL_STEP1(l, p); - length &= ~size_t{1}; - } - if (length == 0) { - *crc = l; - return; - } - // length is now multiple of 16. - // For small blocks just run simple loop, because cost of combining multiple // streams is significant. - if (strategy != CutoffStrategy::Unroll64CRC) { - if (length < kSmallCutoff) { - while (length >= 16) { - ABSL_INTERNAL_STEP8(l, p); - ABSL_INTERNAL_STEP8(l, p); - length -= 16; - } - *crc = l; - return; - } - } - - // For medium blocks we run 3 crc streams and combine them as described in - // Intel paper above. Running 4th stream doesn't help, because crc - // instruction has latency 3 and throughput 1. - if (length < kMediumCutoff) { + if (strategy != CutoffStrategy::Unroll64CRC && (length < kSmallCutoff)) { + // fallthrough; Use the same strategy as we do for processing the + // remaining bytes after any other strategy. + } else if (length < kMediumCutoff) { + // For medium blocks we run 3 crc streams and combine them as described in + // Intel paper above. Running 4th stream doesn't help, because crc + // instruction has latency 3 and throughput 1. l64 = l; if (strategy == CutoffStrategy::Fold3) { uint64_t l641 = 0; @@ -449,6 +418,7 @@ p += 64; } } + l = static_cast<uint32_t>(l64); } else { // There is a lot of data, we can ignore combine costs and run all // requested streams (num_crc_streams + num_pclmul_streams), @@ -571,15 +541,26 @@ } else { p = crc_streams[num_crc_streams - 1]; } + l = static_cast<uint32_t>(l64); } - l = static_cast<uint32_t>(l64); + uint64_t remaining_bytes = static_cast<uint64_t>(e - p); + // Process the remaining bytes. while ((e - p) >= 16) { ABSL_INTERNAL_STEP8(l, p); ABSL_INTERNAL_STEP8(l, p); } - // Process the last few bytes - while (p != e) { + + if (remaining_bytes & 8) { + ABSL_INTERNAL_STEP8(l, p); + } + if (remaining_bytes & 4) { + ABSL_INTERNAL_STEP4(l, p); + } + if (remaining_bytes & 2) { + ABSL_INTERNAL_STEP2(l, p); + } + if (remaining_bytes & 1) { ABSL_INTERNAL_STEP1(l, p); } @@ -605,6 +586,8 @@ case CpuType::kAmdRome: case CpuType::kAmdNaples: case CpuType::kAmdMilan: + case CpuType::kAmdGenoa: + case CpuType::kAmdTurin: return new CRC32AcceleratedX86ARMCombinedMultipleStreams< 3, 1, CutoffStrategy::Fold3>(); // PCLMULQDQ is fast, use combined PCLMULQDQ + CRC implementation. @@ -612,6 +595,10 @@ case CpuType::kIntelSkylakeXeon: case CpuType::kIntelBroadwell: case CpuType::kIntelSkylake: + case CpuType::kIntelIcelake: + case CpuType::kIntelSapphirerapids: + case CpuType::kIntelEmeraldrapids: + case CpuType::kIntelGraniterapidsap: return new CRC32AcceleratedX86ARMCombinedMultipleStreams< 3, 2, CutoffStrategy::Fold3>(); // PCLMULQDQ is slow, don't use it. @@ -623,6 +610,7 @@ case CpuType::kArmNeoverseN1: case CpuType::kArmNeoverseN2: case CpuType::kArmNeoverseV1: + case CpuType::kArmNeoverseN3: return new CRC32AcceleratedX86ARMCombinedMultipleStreams< 1, 1, CutoffStrategy::Unroll64CRC>(); case CpuType::kAmpereSiryn:
diff --git a/absl/debugging/BUILD.bazel b/absl/debugging/BUILD.bazel index cd0f1de..edc7423 100644 --- a/absl/debugging/BUILD.bazel +++ b/absl/debugging/BUILD.bazel
@@ -55,6 +55,7 @@ "//absl/base:config", "//absl/base:core_headers", "//absl/base:dynamic_annotations", + "//absl/base:malloc_internal", "//absl/base:raw_logging_internal", ], )
diff --git a/absl/debugging/CMakeLists.txt b/absl/debugging/CMakeLists.txt index 60b138a..52b13fa 100644 --- a/absl/debugging/CMakeLists.txt +++ b/absl/debugging/CMakeLists.txt
@@ -42,6 +42,7 @@ absl::config absl::core_headers absl::dynamic_annotations + absl::malloc_internal absl::raw_logging_internal PUBLIC )
diff --git a/absl/debugging/stacktrace.cc b/absl/debugging/stacktrace.cc index ccecff7..67df814 100644 --- a/absl/debugging/stacktrace.cc +++ b/absl/debugging/stacktrace.cc
@@ -38,40 +38,19 @@ #include <stddef.h> #include <stdint.h> +#include <stdlib.h> #include <algorithm> #include <atomic> +#include <iterator> #include "absl/base/attributes.h" #include "absl/base/config.h" +#include "absl/base/internal/low_level_alloc.h" #include "absl/base/optimization.h" #include "absl/base/port.h" #include "absl/debugging/internal/stacktrace_config.h" -#ifdef ABSL_INTERNAL_HAVE_ALLOCA -#error ABSL_INTERNAL_HAVE_ALLOCA cannot be directly set -#endif - -#ifdef _WIN32 -#include <malloc.h> -#define ABSL_INTERNAL_HAVE_ALLOCA 1 -#else -#ifdef __has_include -#if __has_include(<alloca.h>) -#include <alloca.h> -#define ABSL_INTERNAL_HAVE_ALLOCA 1 -#elif !defined(alloca) -static void* alloca(size_t) noexcept { return nullptr; } -#endif -#endif -#endif - -#ifdef ABSL_INTERNAL_HAVE_ALLOCA -static constexpr bool kHaveAlloca = true; -#else -static constexpr bool kHaveAlloca = false; -#endif - #if defined(ABSL_STACKTRACE_INL_HEADER) #include ABSL_STACKTRACE_INL_HEADER #else @@ -100,18 +79,60 @@ int* sizes, size_t max_depth, int skip_count, const void* uc, int* min_dropped_frames) { + static constexpr size_t kMinPageSize = 4096; + + // Allow up to ~half a page, leaving some slack space for local variables etc. + static constexpr size_t kMaxStackElements = + (kMinPageSize / 2) / (sizeof(*frames) + sizeof(*sizes)); + + // Allocate a buffer dynamically, using the signal-safe allocator. + static constexpr auto allocate = [](size_t num_bytes) -> void* { + base_internal::InitSigSafeArena(); + return base_internal::LowLevelAlloc::AllocWithArena( + num_bytes, base_internal::SigSafeArena()); + }; + + uintptr_t frames_stackbuf[kMaxStackElements]; + int sizes_stackbuf[kMaxStackElements]; + + // We only need to free the buffers if we allocated them with the signal-safe + // allocator. + bool must_free_frames = false; + bool must_free_sizes = false; + bool unwind_with_fixup = internal_stacktrace::ShouldFixUpStack(); + +#ifdef _WIN32 if (unwind_with_fixup) { - if constexpr (kHaveAlloca) { - // Some implementations of FixUpStack may need to be passed frame - // information from Unwind, even if the caller doesn't need that - // information. We allocate the necessary buffers for such implementations - // here. - if (frames == nullptr) { - frames = static_cast<uintptr_t*>(alloca(max_depth * sizeof(*frames))); + // TODO(b/434184677): Fixups are flaky and not supported on Windows + unwind_with_fixup = false; +#ifndef NDEBUG + abort(); +#endif + } +#endif + + if (unwind_with_fixup) { + // Some implementations of FixUpStack may need to be passed frame + // information from Unwind, even if the caller doesn't need that + // information. We allocate the necessary buffers for such implementations + // here. + + if (frames == nullptr) { + if (max_depth <= std::size(frames_stackbuf)) { + frames = frames_stackbuf; + } else { + frames = static_cast<uintptr_t*>(allocate(max_depth * sizeof(*frames))); + must_free_frames = true; } - if (sizes == nullptr) { - sizes = static_cast<int*>(alloca(max_depth * sizeof(*sizes))); + } + + if (sizes == nullptr) { + if (max_depth <= std::size(sizes_stackbuf)) { + sizes = sizes_stackbuf; + } else { + sizes = static_cast<int*>(allocate(max_depth * sizeof(*sizes))); + must_free_sizes = true; } } } @@ -140,6 +161,15 @@ if (unwind_with_fixup) { internal_stacktrace::FixUpStack(result, frames, sizes, max_depth, size); } + + if (must_free_sizes) { + base_internal::LowLevelAlloc::Free(sizes); + } + + if (must_free_frames) { + base_internal::LowLevelAlloc::Free(frames); + } + ABSL_BLOCK_TAIL_CALL_OPTIMIZATION(); return static_cast<int>(size); }
diff --git a/absl/debugging/stacktrace_test.cc b/absl/debugging/stacktrace_test.cc index 16757e7..4f48a89 100644 --- a/absl/debugging/stacktrace_test.cc +++ b/absl/debugging/stacktrace_test.cc
@@ -21,6 +21,7 @@ #include <cerrno> #include <csignal> #include <cstring> +#include <memory> #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -32,6 +33,7 @@ static int g_should_fixup_calls = 0; static int g_fixup_calls = 0; static bool g_enable_fixup = false; +static uintptr_t g_last_fixup_frame_address = 0; #if ABSL_HAVE_ATTRIBUTE_WEAK bool absl::internal_stacktrace::ShouldFixUpStack() { @@ -41,6 +43,11 @@ void absl::internal_stacktrace::FixUpStack(void**, uintptr_t*, int*, size_t, size_t&) { + const void* frame_address = nullptr; +#if ABSL_HAVE_BUILTIN(__builtin_frame_address) + frame_address = __builtin_frame_address(0); +#endif + g_last_fixup_frame_address = reinterpret_cast<uintptr_t>(frame_address); ++g_fixup_calls; } #endif @@ -85,11 +92,21 @@ // This is a separate function to avoid inlining. ABSL_ATTRIBUTE_NOINLINE static void FixupNoFixupEquivalenceNoInline() { +#if !ABSL_HAVE_ATTRIBUTE_WEAK + GTEST_SKIP() << "Need weak symbol support"; +#endif #if defined(__riscv) GTEST_SKIP() << "Skipping test on RISC-V due to pre-existing failure"; #endif +#if defined(_WIN32) + // TODO(b/434184677): Add support for fixups on Windows if needed + GTEST_SKIP() << "Skipping test on Windows due to lack of support for fixups"; +#endif + bool can_rely_on_frame_pointers = false; + if (!can_rely_on_frame_pointers) { + GTEST_SKIP() << "Frame pointers are required, but not guaranteed in OSS"; + } -#if ABSL_HAVE_ATTRIBUTE_WEAK // This test is known not to pass on MSVC (due to weak symbols) const Cleanup restore_state([enable_fixup = g_enable_fixup, @@ -209,18 +226,61 @@ ContainerEq(absl::MakeSpan(b.frames, static_cast<size_t>(b.depth)))); EXPECT_GT(g_should_fixup_calls, 0); EXPECT_GE(g_should_fixup_calls, g_fixup_calls); - - // ========================================================================== -#else - GTEST_SKIP() << "Need weak symbol support"; -#endif } TEST(StackTrace, FixupNoFixupEquivalence) { FixupNoFixupEquivalenceNoInline(); } +TEST(StackTrace, FixupLowStackUsage) { +#if !ABSL_HAVE_ATTRIBUTE_WEAK + GTEST_SKIP() << "Skipping test on MSVC due to weak symbols"; +#endif +#if defined(_WIN32) + // TODO(b/434184677): Add support for fixups on Windows if needed + GTEST_SKIP() << "Skipping test on Windows due to lack of support for fixups"; +#endif + + const Cleanup restore_state([enable_fixup = g_enable_fixup, + fixup_calls = g_fixup_calls, + should_fixup_calls = g_should_fixup_calls]() { + g_enable_fixup = enable_fixup; + g_fixup_calls = fixup_calls; + g_should_fixup_calls = should_fixup_calls; + }); + + g_enable_fixup = true; + + // Request a ton of stack frames, regardless of how many are actually used. + // It's fine to request more frames than we have, since functions preallocate + // memory before discovering how high the stack really is, and we're really + // just trying to make sure the preallocations don't overflow the stack. + // + // Note that we loop in order to cover all sides of any branches in the + // implementation that switch allocation behavior (e.g., from stack to heap) + // and to ensure that no sides allocate too much stack space. + constexpr size_t kPageSize = 4096; + for (size_t depth = 2; depth < (1 << 20); depth += depth / 2) { + const auto stack = std::make_unique<void*[]>(depth); + const auto frames = std::make_unique<int[]>(depth); + + absl::GetStackFrames(stack.get(), frames.get(), static_cast<int>(depth), 0); + const void* frame_address = nullptr; +#if ABSL_HAVE_BUILTIN(__builtin_frame_address) + frame_address = __builtin_frame_address(0); +#endif + size_t stack_usage = + reinterpret_cast<uintptr_t>(frame_address) - g_last_fixup_frame_address; + EXPECT_LT(stack_usage, kPageSize); + } +} + TEST(StackTrace, CustomUnwinderPerformsFixup) { -#if ABSL_HAVE_ATTRIBUTE_WEAK - // This test is known not to pass on MSVC (due to weak symbols) +#if !ABSL_HAVE_ATTRIBUTE_WEAK + GTEST_SKIP() << "Need weak symbol support"; +#endif +#if defined(_WIN32) + // TODO(b/434184677): Add support for fixups on Windows if needed + GTEST_SKIP() << "Skipping test on Windows due to lack of support for fixups"; +#endif constexpr int kSkip = 1; // Skip our own frame, whose return PCs won't match constexpr auto kStackCount = 1; @@ -266,9 +326,6 @@ nullptr, nullptr); EXPECT_GT(g_should_fixup_calls, 0); EXPECT_GT(g_fixup_calls, 0); -#else - GTEST_SKIP() << "Need weak symbol support"; -#endif } #if ABSL_HAVE_BUILTIN(__builtin_frame_address)
diff --git a/absl/flags/internal/flag.cc b/absl/flags/internal/flag.cc index 37f6ef1..b05e1bd 100644 --- a/absl/flags/internal/flag.cc +++ b/absl/flags/internal/flag.cc
@@ -73,8 +73,8 @@ // need to acquire these locks themselves. class MutexRelock { public: - explicit MutexRelock(absl::Mutex& mu) : mu_(mu) { mu_.Unlock(); } - ~MutexRelock() { mu_.Lock(); } + explicit MutexRelock(absl::Mutex& mu) : mu_(mu) { mu_.unlock(); } + ~MutexRelock() { mu_.lock(); } MutexRelock(const MutexRelock&) = delete; MutexRelock& operator=(const MutexRelock&) = delete; @@ -88,9 +88,9 @@ // we move the memory to the freelist where it lives indefinitely, so it can // still be safely accessed. This also prevents leak checkers from complaining // about the leaked memory that can no longer be accessed through any pointer. -absl::Mutex* FreelistMutex() { +absl::Mutex& FreelistMutex() { static absl::NoDestructor<absl::Mutex> mutex; - return mutex.get(); + return *mutex; } ABSL_CONST_INIT std::vector<void*>* s_freelist ABSL_GUARDED_BY(FreelistMutex()) ABSL_PT_GUARDED_BY(FreelistMutex()) = nullptr; @@ -248,12 +248,12 @@ seq_lock_.MarkInitialized(); } -absl::Mutex* FlagImpl::DataGuard() const { +absl::Mutex& FlagImpl::DataGuard() const { absl::call_once(const_cast<FlagImpl*>(this)->init_control_, &FlagImpl::Init, const_cast<FlagImpl*>(this)); // data_guard_ is initialized inside Init. - return reinterpret_cast<absl::Mutex*>(&data_guard_); + return *reinterpret_cast<absl::Mutex*>(&data_guard_); } void FlagImpl::AssertValidType(FlagFastTypeId rhs_type_id, @@ -375,7 +375,7 @@ } std::string FlagImpl::CurrentValue() const { - auto* guard = DataGuard(); // Make sure flag initialized + auto& guard = DataGuard(); // Make sure flag initialized switch (ValueStorageKind()) { case FlagValueStorageKind::kValueAndInitBit: case FlagValueStorageKind::kOneWordAtomic: { @@ -429,8 +429,8 @@ // and it also can be different by the time the callback invocation is // completed. Requires that *primary_lock be held in exclusive mode; it may be // released and reacquired by the implementation. - MutexRelock relock(*DataGuard()); - absl::MutexLock lock(&callback_->guard); + MutexRelock relock(DataGuard()); + absl::MutexLock lock(callback_->guard); cb(); } @@ -535,7 +535,7 @@ } void FlagImpl::Read(void* dst) const { - auto* guard = DataGuard(); // Make sure flag initialized + auto& guard = DataGuard(); // Make sure flag initialized switch (ValueStorageKind()) { case FlagValueStorageKind::kValueAndInitBit: case FlagValueStorageKind::kOneWordAtomic: { @@ -567,14 +567,14 @@ int64_t FlagImpl::ReadOneWord() const { assert(ValueStorageKind() == FlagValueStorageKind::kOneWordAtomic || ValueStorageKind() == FlagValueStorageKind::kValueAndInitBit); - auto* guard = DataGuard(); // Make sure flag initialized + auto& guard = DataGuard(); // Make sure flag initialized (void)guard; return OneWordValue().load(std::memory_order_acquire); } bool FlagImpl::ReadOneBool() const { assert(ValueStorageKind() == FlagValueStorageKind::kValueAndInitBit); - auto* guard = DataGuard(); // Make sure flag initialized + auto& guard = DataGuard(); // Make sure flag initialized (void)guard; return absl::bit_cast<FlagValueAndInitBit<bool>>( OneWordValue().load(std::memory_order_acquire))
diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h index b61a247..cab9d16 100644 --- a/absl/flags/internal/flag.h +++ b/absl/flags/internal/flag.h
@@ -601,17 +601,17 @@ data_guard_{} {} // Constant access methods - int64_t ReadOneWord() const ABSL_LOCKS_EXCLUDED(*DataGuard()); - bool ReadOneBool() const ABSL_LOCKS_EXCLUDED(*DataGuard()); - void Read(void* dst) const override ABSL_LOCKS_EXCLUDED(*DataGuard()); - void Read(bool* value) const ABSL_LOCKS_EXCLUDED(*DataGuard()) { + int64_t ReadOneWord() const ABSL_LOCKS_EXCLUDED(DataGuard()); + bool ReadOneBool() const ABSL_LOCKS_EXCLUDED(DataGuard()); + void Read(void* dst) const override ABSL_LOCKS_EXCLUDED(DataGuard()); + void Read(bool* value) const ABSL_LOCKS_EXCLUDED(DataGuard()) { *value = ReadOneBool(); } template <typename T, absl::enable_if_t<flags_internal::StorageKind<T>() == FlagValueStorageKind::kOneWordAtomic, int> = 0> - void Read(T* value) const ABSL_LOCKS_EXCLUDED(*DataGuard()) { + void Read(T* value) const ABSL_LOCKS_EXCLUDED(DataGuard()) { int64_t v = ReadOneWord(); std::memcpy(value, static_cast<const void*>(&v), sizeof(T)); } @@ -619,17 +619,17 @@ typename std::enable_if<flags_internal::StorageKind<T>() == FlagValueStorageKind::kValueAndInitBit, int>::type = 0> - void Read(T* value) const ABSL_LOCKS_EXCLUDED(*DataGuard()) { + void Read(T* value) const ABSL_LOCKS_EXCLUDED(DataGuard()) { *value = absl::bit_cast<FlagValueAndInitBit<T>>(ReadOneWord()).value; } // Mutating access methods - void Write(const void* src) ABSL_LOCKS_EXCLUDED(*DataGuard()); + void Write(const void* src) ABSL_LOCKS_EXCLUDED(DataGuard()); // Interfaces to operate on callbacks. void SetCallback(const FlagCallbackFunc mutation_callback) - ABSL_LOCKS_EXCLUDED(*DataGuard()); - void InvokeCallback() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()); + ABSL_LOCKS_EXCLUDED(DataGuard()); + void InvokeCallback() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(DataGuard()); // Used in read/write operations to validate source/target has correct type. // For example if flag is declared as absl::Flag<int> FLAGS_foo, a call to @@ -646,11 +646,11 @@ friend class FlagState; // Ensures that `data_guard_` is initialized and returns it. - absl::Mutex* DataGuard() const + absl::Mutex& DataGuard() const ABSL_LOCK_RETURNED(reinterpret_cast<absl::Mutex*>(data_guard_)); // Returns heap allocated value of type T initialized with default value. std::unique_ptr<void, DynValueDeleter> MakeInitValue() const - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()); + ABSL_EXCLUSIVE_LOCKS_REQUIRED(DataGuard()); // Flag initialization called via absl::call_once. void Init(); @@ -676,16 +676,15 @@ // returns new value. Otherwise returns nullptr. std::unique_ptr<void, DynValueDeleter> TryParse(absl::string_view value, std::string& err) const - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()); + ABSL_EXCLUSIVE_LOCKS_REQUIRED(DataGuard()); // Stores the flag value based on the pointer to the source. void StoreValue(const void* src, ValueSource source) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()); + ABSL_EXCLUSIVE_LOCKS_REQUIRED(DataGuard()); // Copy the flag data, protected by `seq_lock_` into `dst`. // // REQUIRES: ValueStorageKind() == kSequenceLocked. - void ReadSequenceLockedData(void* dst) const - ABSL_LOCKS_EXCLUDED(*DataGuard()); + void ReadSequenceLockedData(void* dst) const ABSL_LOCKS_EXCLUDED(DataGuard()); FlagHelpKind HelpSourceKind() const { return static_cast<FlagHelpKind>(help_source_kind_); @@ -694,7 +693,7 @@ return static_cast<FlagValueStorageKind>(value_storage_kind_); } FlagDefaultKind DefaultKind() const - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()) { + ABSL_EXCLUSIVE_LOCKS_REQUIRED(DataGuard()) { return static_cast<FlagDefaultKind>(def_kind_); } @@ -705,30 +704,30 @@ std::string Help() const override; FlagFastTypeId TypeId() const override; bool IsSpecifiedOnCommandLine() const override - ABSL_LOCKS_EXCLUDED(*DataGuard()); - std::string DefaultValue() const override ABSL_LOCKS_EXCLUDED(*DataGuard()); - std::string CurrentValue() const override ABSL_LOCKS_EXCLUDED(*DataGuard()); + ABSL_LOCKS_EXCLUDED(DataGuard()); + std::string DefaultValue() const override ABSL_LOCKS_EXCLUDED(DataGuard()); + std::string CurrentValue() const override ABSL_LOCKS_EXCLUDED(DataGuard()); bool ValidateInputValue(absl::string_view value) const override - ABSL_LOCKS_EXCLUDED(*DataGuard()); + ABSL_LOCKS_EXCLUDED(DataGuard()); void CheckDefaultValueParsingRoundtrip() const override - ABSL_LOCKS_EXCLUDED(*DataGuard()); + ABSL_LOCKS_EXCLUDED(DataGuard()); - int64_t ModificationCount() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()); + int64_t ModificationCount() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(DataGuard()); // Interfaces to save and restore flags to/from persistent state. // Returns current flag state or nullptr if flag does not support // saving and restoring a state. std::unique_ptr<FlagStateInterface> SaveState() override - ABSL_LOCKS_EXCLUDED(*DataGuard()); + ABSL_LOCKS_EXCLUDED(DataGuard()); // Restores the flag state to the supplied state object. If there is // nothing to restore returns false. Otherwise returns true. bool RestoreState(const FlagState& flag_state) - ABSL_LOCKS_EXCLUDED(*DataGuard()); + ABSL_LOCKS_EXCLUDED(DataGuard()); bool ParseFrom(absl::string_view value, FlagSettingMode set_mode, ValueSource source, std::string& error) override - ABSL_LOCKS_EXCLUDED(*DataGuard()); + ABSL_LOCKS_EXCLUDED(DataGuard()); // Immutable flag's state. @@ -758,9 +757,9 @@ // locks. uint8_t def_kind_ : 2; // Has this flag's value been modified? - bool modified_ : 1 ABSL_GUARDED_BY(*DataGuard()); + bool modified_ : 1 ABSL_GUARDED_BY(DataGuard()); // Has this flag been specified on command line. - bool on_command_line_ : 1 ABSL_GUARDED_BY(*DataGuard()); + bool on_command_line_ : 1 ABSL_GUARDED_BY(DataGuard()); // Unique tag for absl::call_once call to initialize this flag. absl::once_flag init_control_; @@ -769,7 +768,7 @@ flags_internal::SequenceLock seq_lock_; // Optional flag's callback and absl::Mutex to guard the invocations. - FlagCallback* callback_ ABSL_GUARDED_BY(*DataGuard()); + FlagCallback* callback_ ABSL_GUARDED_BY(DataGuard()); // Either a pointer to the function generating the default value based on the // value specified in ABSL_FLAG or pointer to the dynamically set default // value via SetCommandLineOptionWithMode. def_kind_ is used to distinguish
diff --git a/absl/flags/internal/program_name.cc b/absl/flags/internal/program_name.cc index fb06643..23185c6 100644 --- a/absl/flags/internal/program_name.cc +++ b/absl/flags/internal/program_name.cc
@@ -29,9 +29,9 @@ ABSL_NAMESPACE_BEGIN namespace flags_internal { -static absl::Mutex* ProgramNameMutex() { +static absl::Mutex& ProgramNameMutex() { static absl::NoDestructor<absl::Mutex> mutex; - return mutex.get(); + return *mutex; } ABSL_CONST_INIT static std::string* program_name ABSL_GUARDED_BY( ProgramNameMutex()) ABSL_PT_GUARDED_BY(ProgramNameMutex()) = nullptr;
diff --git a/absl/flags/internal/usage.cc b/absl/flags/internal/usage.cc index fc68b03..3c44271 100644 --- a/absl/flags/internal/usage.cc +++ b/absl/flags/internal/usage.cc
@@ -434,9 +434,9 @@ namespace { -absl::Mutex* HelpAttributesMutex() { +absl::Mutex& HelpAttributesMutex() { static absl::NoDestructor<absl::Mutex> mutex; - return mutex.get(); + return *mutex; } ABSL_CONST_INIT std::string* match_substr ABSL_GUARDED_BY(HelpAttributesMutex()) ABSL_PT_GUARDED_BY(HelpAttributesMutex()) = nullptr;
diff --git a/absl/flags/parse.cc b/absl/flags/parse.cc index c87cacd..df2a179 100644 --- a/absl/flags/parse.cc +++ b/absl/flags/parse.cc
@@ -64,9 +64,9 @@ namespace flags_internal { namespace { -absl::Mutex* ProcessingChecksMutex() { +absl::Mutex& ProcessingChecksMutex() { static absl::NoDestructor<absl::Mutex> mutex; - return mutex.get(); + return *mutex; } ABSL_CONST_INIT bool flagfile_needs_processing @@ -76,9 +76,9 @@ ABSL_CONST_INIT bool tryfromenv_needs_processing ABSL_GUARDED_BY(ProcessingChecksMutex()) = false; -absl::Mutex* SpecifiedFlagsMutex() { +absl::Mutex& SpecifiedFlagsMutex() { static absl::NoDestructor<absl::Mutex> mutex; - return mutex.get(); + return *mutex; } ABSL_CONST_INIT std::vector<const CommandLineFlag*>* specified_flags
diff --git a/absl/flags/reflection.cc b/absl/flags/reflection.cc index b8b4a2e..845099e 100644 --- a/absl/flags/reflection.cc +++ b/absl/flags/reflection.cc
@@ -53,8 +53,11 @@ // Store a flag in this registry. Takes ownership of *flag. void RegisterFlag(CommandLineFlag& flag, const char* filename); - void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION(lock_) { lock_.Lock(); } - void Unlock() ABSL_UNLOCK_FUNCTION(lock_) { lock_.Unlock(); } + void lock() ABSL_EXCLUSIVE_LOCK_FUNCTION(lock_) { lock_.lock(); } + inline void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION(lock_) { lock(); } + + void unlock() ABSL_UNLOCK_FUNCTION(lock_) { lock_.unlock(); } + inline void Unlock() ABSL_UNLOCK_FUNCTION(lock_) { unlock(); } // Returns the flag object for the specified name, or nullptr if not found. // Will emit a warning if a 'retired' flag is specified. @@ -87,8 +90,8 @@ class FlagRegistryLock { public: - explicit FlagRegistryLock(FlagRegistry& fr) : fr_(fr) { fr_.Lock(); } - ~FlagRegistryLock() { fr_.Unlock(); } + explicit FlagRegistryLock(FlagRegistry& fr) : fr_(fr) { fr_.lock(); } + ~FlagRegistryLock() { fr_.unlock(); } private: FlagRegistry& fr_;
diff --git a/absl/flags/usage.cc b/absl/flags/usage.cc index 267a503..e42b454 100644 --- a/absl/flags/usage.cc +++ b/absl/flags/usage.cc
@@ -40,7 +40,7 @@ // -------------------------------------------------------------------- // Sets the "usage" message to be used by help reporting routines. void SetProgramUsageMessage(absl::string_view new_usage_message) { - absl::MutexLock l(&flags_internal::usage_message_guard); + absl::MutexLock l(flags_internal::usage_message_guard); if (flags_internal::program_usage_message != nullptr) { ABSL_INTERNAL_LOG(FATAL, "SetProgramUsageMessage() called twice."); @@ -55,7 +55,7 @@ // Note: We able to return string_view here only because calling // SetProgramUsageMessage twice is prohibited. absl::string_view ProgramUsageMessage() { - absl::MutexLock l(&flags_internal::usage_message_guard); + absl::MutexLock l(flags_internal::usage_message_guard); return flags_internal::program_usage_message != nullptr ? absl::string_view(*flags_internal::program_usage_message)
diff --git a/absl/flags/usage_config.cc b/absl/flags/usage_config.cc index 5922c5e..bbc020d 100644 --- a/absl/flags/usage_config.cc +++ b/absl/flags/usage_config.cc
@@ -105,9 +105,9 @@ // -------------------------------------------------------------------- -absl::Mutex* CustomUsageConfigMutex() { +absl::Mutex& CustomUsageConfigMutex() { static absl::NoDestructor<absl::Mutex> mutex; - return mutex.get(); + return *mutex; } ABSL_CONST_INIT FlagsUsageConfig* custom_usage_config ABSL_GUARDED_BY(CustomUsageConfigMutex())
diff --git a/absl/functional/BUILD.bazel b/absl/functional/BUILD.bazel index c2bb96d..f9c58d4 100644 --- a/absl/functional/BUILD.bazel +++ b/absl/functional/BUILD.bazel
@@ -44,6 +44,7 @@ deps = [ "//absl/base:config", "//absl/base:core_headers", + "//absl/base:nullability", "//absl/meta:type_traits", "//absl/utility", ], @@ -61,6 +62,7 @@ ":any_invocable", "//absl/base:config", "//absl/base:core_headers", + "//absl/base:nullability", "//absl/meta:type_traits", "//absl/utility", "@googletest//:gtest",
diff --git a/absl/functional/CMakeLists.txt b/absl/functional/CMakeLists.txt index 91939db..34d285d 100644 --- a/absl/functional/CMakeLists.txt +++ b/absl/functional/CMakeLists.txt
@@ -24,6 +24,7 @@ COPTS ${ABSL_DEFAULT_COPTS} DEPS + absl::base absl::config absl::core_headers absl::type_traits @@ -41,6 +42,7 @@ ${ABSL_TEST_COPTS} DEPS absl::any_invocable + absl::base absl::config absl::core_headers absl::type_traits
diff --git a/absl/functional/any_invocable.h b/absl/functional/any_invocable.h index 524345d..ade6cff 100644 --- a/absl/functional/any_invocable.h +++ b/absl/functional/any_invocable.h
@@ -40,6 +40,7 @@ #include <utility> #include "absl/base/config.h" +#include "absl/base/nullability.h" #include "absl/functional/internal/any_invocable.h" #include "absl/meta/type_traits.h" #include "absl/utility/utility.h" @@ -158,7 +159,8 @@ // AnyInvocable<void()> empty; // empty(); // WARNING: Undefined behavior! template <class Sig> -class AnyInvocable : private internal_any_invocable::Impl<Sig> { +class ABSL_NULLABILITY_COMPATIBLE AnyInvocable + : private internal_any_invocable::Impl<Sig> { private: static_assert( std::is_function<Sig>::value,
diff --git a/absl/functional/any_invocable_test.cc b/absl/functional/any_invocable_test.cc index 6ad6323..7ddfcab 100644 --- a/absl/functional/any_invocable_test.cc +++ b/absl/functional/any_invocable_test.cc
@@ -15,13 +15,17 @@ #include "absl/functional/any_invocable.h" #include <cstddef> +#include <cstdlib> +#include <functional> #include <initializer_list> +#include <iterator> #include <memory> #include <numeric> #include <type_traits> #include "gtest/gtest.h" #include "absl/base/config.h" +#include "absl/base/nullability.h" #include "absl/meta/type_traits.h" #include "absl/utility/utility.h" @@ -652,8 +656,8 @@ TYPED_TEST_P(AnyInvTestBasic, MoveConstructionFromEmpty) { using AnyInvType = typename TypeParam::AnyInvType; - AnyInvType source_fun; - AnyInvType fun(std::move(source_fun)); + absl_nullable AnyInvType source_fun; + absl_nullable AnyInvType fun(std::move(source_fun)); EXPECT_FALSE(static_cast<bool>(fun));
diff --git a/absl/functional/internal/any_invocable.h b/absl/functional/internal/any_invocable.h index 167d947..a696fdd 100644 --- a/absl/functional/internal/any_invocable.h +++ b/absl/functional/internal/any_invocable.h
@@ -66,6 +66,7 @@ #include "absl/base/attributes.h" #include "absl/base/config.h" #include "absl/base/macros.h" +#include "absl/base/nullability.h" #include "absl/base/optimization.h" #include "absl/meta/type_traits.h" #include "absl/utility/utility.h" @@ -75,7 +76,7 @@ // Defined in functional/any_invocable.h template <class Sig> -class AnyInvocable; +class ABSL_NULLABILITY_COMPATIBLE AnyInvocable; namespace internal_any_invocable {
diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h index 8c584b2..2f91a8b 100644 --- a/absl/hash/internal/hash.h +++ b/absl/hash/internal/hash.h
@@ -88,7 +88,8 @@ #include "absl/types/variant.h" #include "absl/utility/utility.h" -#if defined(__cpp_lib_filesystem) && __cpp_lib_filesystem >= 201703L +#if defined(__cpp_lib_filesystem) && __cpp_lib_filesystem >= 201703L && \ + !defined(__XTENSA__) #include <filesystem> // NOLINT #endif @@ -633,7 +634,8 @@ (!defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) || \ __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 130000) && \ (!defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) || \ - __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101500) + __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101500) && \ + (!defined(__XTENSA__)) #define ABSL_INTERNAL_STD_FILESYSTEM_PATH_HASH_AVAILABLE 1
diff --git a/absl/log/BUILD.bazel b/absl/log/BUILD.bazel index d4b3730..3e965ab 100644 --- a/absl/log/BUILD.bazel +++ b/absl/log/BUILD.bazel
@@ -154,6 +154,7 @@ cc_library( name = "log_entry", + srcs = ["log_entry.cc"], hdrs = ["log_entry.h"], copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, @@ -162,6 +163,7 @@ "//absl/base:core_headers", "//absl/base:log_severity", "//absl/log/internal:config", + "//absl/log/internal:proto", "//absl/strings", "//absl/time", "//absl/types:span",
diff --git a/absl/log/CMakeLists.txt b/absl/log/CMakeLists.txt index 130897f..eb19bec 100644 --- a/absl/log/CMakeLists.txt +++ b/absl/log/CMakeLists.txt
@@ -560,6 +560,8 @@ absl_cc_library( NAME log_entry + SRCS + "log_entry.cc" HDRS "log_entry.h" COPTS @@ -570,6 +572,7 @@ absl::config absl::core_headers absl::log_internal_config + absl::log_internal_proto absl::log_severity absl::span absl::strings
diff --git a/absl/log/flags_test.cc b/absl/log/flags_test.cc index 1080ea1..f5a2b51 100644 --- a/absl/log/flags_test.cc +++ b/absl/log/flags_test.cc
@@ -93,6 +93,7 @@ TEST_F(LogFlagsTest, EmptyBacktraceAtFlag) { absl::SetMinLogLevel(absl::LogSeverityAtLeast::kInfo); absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send(TextMessage(Not(HasSubstr("(stacktrace:"))))); @@ -104,6 +105,7 @@ TEST_F(LogFlagsTest, BacktraceAtNonsense) { absl::SetMinLogLevel(absl::LogSeverityAtLeast::kInfo); absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send(TextMessage(Not(HasSubstr("(stacktrace:"))))); @@ -117,6 +119,7 @@ const int log_line = __LINE__ + 1; auto do_log = [] { LOG(INFO) << "hello world"; }; absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send(TextMessage(Not(HasSubstr("(stacktrace:"))))); @@ -131,6 +134,7 @@ const int log_line = __LINE__ + 1; auto do_log = [] { LOG(INFO) << "hello world"; }; absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send(TextMessage(Not(HasSubstr("(stacktrace:"))))); @@ -145,6 +149,7 @@ const int log_line = __LINE__ + 1; auto do_log = [] { LOG(INFO) << "hello world"; }; absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send(TextMessage(Not(HasSubstr("(stacktrace:"))))); @@ -158,6 +163,7 @@ const int log_line = __LINE__ + 1; auto do_log = [] { LOG(INFO) << "hello world"; }; absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send(TextMessage(Not(HasSubstr("(stacktrace:"))))); @@ -172,6 +178,7 @@ const int log_line = __LINE__ + 1; auto do_log = [] { LOG(INFO) << "hello world"; }; absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); testing::InSequence seq; EXPECT_CALL(test_sink, Send(TextMessage(HasSubstr("(stacktrace:"))));
diff --git a/absl/log/internal/log_sink_set.cc b/absl/log/internal/log_sink_set.cc index 3d5c699..c4c7e5f 100644 --- a/absl/log/internal/log_sink_set.cc +++ b/absl/log/internal/log_sink_set.cc
@@ -192,7 +192,7 @@ absl::log_internal::WriteToStderr( entry.text_message_with_prefix_and_newline(), entry.log_severity()); } else { - absl::ReaderMutexLock global_sinks_lock(&guard_); + absl::ReaderMutexLock global_sinks_lock(guard_); ThreadIsLoggingStatus() = true; // Ensure the "thread is logging" status is reverted upon leaving the // scope even in case of exceptions. @@ -205,7 +205,7 @@ void AddLogSink(absl::LogSink* sink) ABSL_LOCKS_EXCLUDED(guard_) { { - absl::WriterMutexLock global_sinks_lock(&guard_); + absl::WriterMutexLock global_sinks_lock(guard_); auto pos = std::find(sinks_.begin(), sinks_.end(), sink); if (pos == sinks_.end()) { sinks_.push_back(sink); @@ -217,7 +217,7 @@ void RemoveLogSink(absl::LogSink* sink) ABSL_LOCKS_EXCLUDED(guard_) { { - absl::WriterMutexLock global_sinks_lock(&guard_); + absl::WriterMutexLock global_sinks_lock(guard_); auto pos = std::find(sinks_.begin(), sinks_.end(), sink); if (pos != sinks_.end()) { sinks_.erase(pos); @@ -235,7 +235,7 @@ guard_.AssertReaderHeld(); FlushLogSinksLocked(); } else { - absl::ReaderMutexLock global_sinks_lock(&guard_); + absl::ReaderMutexLock global_sinks_lock(guard_); // In case if LogSink::Flush overload decides to log ThreadIsLoggingStatus() = true; // Ensure the "thread is logging" status is reverted upon leaving the
diff --git a/absl/log/internal/vlog_config.cc b/absl/log/internal/vlog_config.cc index 0a460d9..f70069f 100644 --- a/absl/log/internal/vlog_config.cc +++ b/absl/log/internal/vlog_config.cc
@@ -94,12 +94,12 @@ // `GetUpdateSitesMutex()` serializes updates to all of the sites (i.e. those in // `site_list_head`) themselves. -absl::Mutex* GetUpdateSitesMutex() { +absl::Mutex& GetUpdateSitesMutex() { // Chromium requires no global destructors, so we can't use the // absl::kConstInit idiom since absl::Mutex as a non-trivial destructor. static absl::NoDestructor<absl::Mutex> update_sites_mutex ABSL_ACQUIRED_AFTER( mutex); - return update_sites_mutex.get(); + return *update_sites_mutex; } ABSL_CONST_INIT int global_v ABSL_GUARDED_BY(mutex) = 0; @@ -222,7 +222,7 @@ } // namespace int VLogLevel(absl::string_view file) ABSL_LOCKS_EXCLUDED(mutex) { - absl::base_internal::SpinLockHolder l(&mutex); + absl::base_internal::SpinLockHolder l(mutex); return VLogLevel(file, vmodule_info, global_v); }
diff --git a/absl/log/log_basic_test_impl.inc b/absl/log/log_basic_test_impl.inc index c4b4e24..3f007dc 100644 --- a/absl/log/log_basic_test_impl.inc +++ b/absl/log/log_basic_test_impl.inc
@@ -94,6 +94,7 @@ absl::log_internal::ScopedMinLogLevel scoped_min_log_level(GetParam()); absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const int log_line = __LINE__ + 1; auto do_log = [] { ABSL_TEST_LOG(INFO) << "hello world"; }; @@ -125,6 +126,7 @@ absl::log_internal::ScopedMinLogLevel scoped_min_log_level(GetParam()); absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const int log_line = __LINE__ + 1; auto do_log = [] { ABSL_TEST_LOG(WARNING) << "hello world"; }; @@ -156,6 +158,7 @@ absl::log_internal::ScopedMinLogLevel scoped_min_log_level(GetParam()); absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const int log_line = __LINE__ + 1; auto do_log = [] { ABSL_TEST_LOG(ERROR) << "hello world"; }; @@ -187,6 +190,7 @@ absl::log_internal::ScopedMinLogLevel scoped_min_log_level(GetParam()); absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const int log_line = __LINE__ + 1; auto do_log = [] { ABSL_TEST_LOG(DO_NOT_SUBMIT) << "hello world"; }; @@ -233,6 +237,7 @@ { absl::ScopedMockLog test_sink( absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send) .Times(AnyNumber()) @@ -299,6 +304,7 @@ { absl::ScopedMockLog test_sink( absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send) .Times(AnyNumber()) @@ -336,6 +342,7 @@ absl::log_internal::ScopedMinLogLevel scoped_min_log_level(GetParam()); absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const int log_line = __LINE__ + 1; auto do_log = [] { ABSL_TEST_LOG(DFATAL) << "hello world"; }; @@ -375,6 +382,7 @@ { absl::ScopedMockLog test_sink( absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send) .Times(AnyNumber()) @@ -456,6 +464,7 @@ for (auto severity : {absl::LogSeverity::kInfo, absl::LogSeverity::kWarning, absl::LogSeverity::kError}) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const int log_line = __LINE__ + 2; auto do_log = [severity] { @@ -506,6 +515,7 @@ { absl::ScopedMockLog test_sink( absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send) .Times(AnyNumber()) @@ -567,6 +577,7 @@ } absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send(LogSeverity(Eq(absl::LogSeverity::kInfo)))); @@ -583,6 +594,7 @@ } absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send(LogSeverity(Eq(absl::LogSeverity::kError))));
diff --git a/absl/log/log_entry.cc b/absl/log/log_entry.cc new file mode 100644 index 0000000..358b8f5 --- /dev/null +++ b/absl/log/log_entry.cc
@@ -0,0 +1,263 @@ +// Copyright 2025 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/log/log_entry.h" + +#include <cstddef> +#include <cstdint> +#include <iomanip> +#include <ios> +#include <ostream> + +#include "absl/base/config.h" +#include "absl/log/internal/proto.h" +#include "absl/strings/escaping.h" +#include "absl/strings/string_view.h" +#include "absl/time/time.h" +#include "absl/types/span.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace { +// message `logging.proto.Event` +enum EventTag : uint8_t { + kFileName = 2, + kFileLine = 3, + kTimeNsecs = 4, + kSeverity = 5, + kThreadId = 6, + kValue = 7, + kSequenceNumber = 9, + kThreadName = 10, +}; + +// message `logging.proto.Value` +enum ValueTag : uint8_t { + kString = 1, + kStringLiteral = 6, +}; + +// enum `logging.proto.Severity` +enum Severity : int { + FINEST = 300, + FINER = 400, + FINE = 500, + VERBOSE_0 = 600, + CONFIG = 700, + INFO = 800, + NOTICE = 850, + WARNING = 900, + ERROR = 950, + SEVERE = 1000, + FATAL = 1100, +}; + +void PrintEscapedRangeTo(const absl::string_view str, + const absl::string_view substr, std::ostream* os) { + const absl::string_view head = + str.substr(0, static_cast<size_t>(substr.data() - str.data())); + const char old_fill = os->fill(); + const auto old_flags = os->flags(); + *os << std::right + << std::setw(static_cast<int>(absl::CHexEscape(head).size())) << ""; + switch (substr.size()) { + case 0: + *os << "\\"; + break; + case 1: + *os << "^"; + break; + default: + *os << "[" << std::setw(static_cast<int>(absl::CHexEscape(substr).size())) + << std::setfill('-') << ")"; + break; + } + os->fill(old_fill); + os->flags(old_flags); +} +} // namespace +void PrintTo(const LogEntry& entry, std::ostream* os) { + auto text_message_with_prefix_and_newline_and_nul = absl::string_view( + entry.text_message_with_prefix_and_newline_and_nul_.data(), + entry.text_message_with_prefix_and_newline_and_nul_.size()); + *os << "LogEntry {\n" + << " source_filename: \"" << absl::CHexEscape(entry.source_filename()) + << "\"\n" + << " source_basename: \"" << absl::CHexEscape(entry.source_basename()) + << "\"\n" + << " source_line: " << entry.source_line() << "\n" + << " prefix: " << std::boolalpha << entry.prefix() << "\n" + << " log_severity: " << entry.log_severity() << "\n" + << " verbosity: " << entry.verbosity(); + if (entry.verbosity() == absl::LogEntry::kNoVerbosityLevel) { + *os << " (kNoVerbosityLevel)"; + } + *os << "\n" + << " timestamp: " << entry.timestamp() << "\n" + << " tid: " << entry.tid() << "\n" + << " text_message_with_prefix_and_newline_and_nul_: \"" + << absl::CHexEscape(text_message_with_prefix_and_newline_and_nul) + << "\"\n" + << " text_message_with_prefix_and_newline: "; + PrintEscapedRangeTo(text_message_with_prefix_and_newline_and_nul, + entry.text_message_with_prefix_and_newline(), os); + *os << "\n" + << " text_message_with_prefix: "; + PrintEscapedRangeTo(text_message_with_prefix_and_newline_and_nul, + entry.text_message_with_prefix(), os); + *os << "\n" + << " text_message_with_newline: "; + PrintEscapedRangeTo(text_message_with_prefix_and_newline_and_nul, + entry.text_message_with_newline(), os); + *os << "\n" + << " text_message: "; + PrintEscapedRangeTo(text_message_with_prefix_and_newline_and_nul, + entry.text_message(), os); + *os << "\n" + << " text_message_with_prefix_and_newline_c_str: "; + PrintEscapedRangeTo( + text_message_with_prefix_and_newline_and_nul, + // NOLINTNEXTLINE(bugprone-string-constructor) + absl::string_view(entry.text_message_with_prefix_and_newline_c_str(), 0), + os); + *os << "\n" + << " encoded_message (raw): \"" + << absl::CHexEscape(entry.encoded_message()) << "\"\n" + << " encoded_message {\n"; + absl::Span<const char> event = entry.encoded_message(); + log_internal::ProtoField field; + while (field.DecodeFrom(&event)) { + switch (field.tag()) { + case EventTag::kFileName: + *os << " file_name: \"" << absl::CHexEscape(field.string_value()) + << "\"\n"; + break; + case EventTag::kFileLine: + *os << " file_line: " << field.int32_value() << "\n"; + break; + case EventTag::kTimeNsecs: + *os << " time_nsecs: " << field.int64_value() << " (" + << absl::FromUnixNanos(field.int64_value()) << ")\n"; + break; + case EventTag::kSeverity: + *os << " severity: " << field.int32_value(); + switch (field.int32_value()) { + case Severity::FINEST: + *os << " (FINEST)"; + break; + case Severity::FINER: + *os << " (FINER)"; + break; + case Severity::FINE: + *os << " (FINE)"; + break; + case Severity::VERBOSE_0: + *os << " (VERBOSE_0)"; + break; + case Severity::CONFIG: + *os << " (CONFIG)"; + break; + case Severity::INFO: + *os << " (INFO)"; + break; + case Severity::NOTICE: + *os << " (NOTICE)"; + break; + case Severity::WARNING: + *os << " (WARNING)"; + break; + case Severity::ERROR: + *os << " (ERROR)"; + break; + case Severity::SEVERE: + *os << " (SEVERE)"; + break; + case Severity::FATAL: + *os << " (FATAL)"; + break; + } + *os << "\n"; + break; + case EventTag::kThreadId: + *os << " thread_id: " << field.int64_value() << "\n"; + break; + case EventTag::kValue: { + *os << " value {\n"; + auto value = field.bytes_value(); + while (field.DecodeFrom(&value)) { + switch (field.tag()) { + case ValueTag::kString: + *os << " str: \"" << absl::CHexEscape(field.string_value()) + << "\"\n"; + break; + case ValueTag::kStringLiteral: + *os << " literal: \"" + << absl::CHexEscape(field.string_value()) << "\"\n"; + break; + default: + *os << " unknown field " << field.tag(); + switch (field.type()) { + case log_internal::WireType::kVarint: + *os << " (VARINT): " << std::hex << std::showbase + << field.uint64_value() << std::dec << "\n"; + break; + case log_internal::WireType::k64Bit: + *os << " (I64): " << std::hex << std::showbase + << field.uint64_value() << std::dec << "\n"; + break; + case log_internal::WireType::kLengthDelimited: + *os << " (LEN): \"" << absl::CHexEscape(field.string_value()) + << "\"\n"; + break; + case log_internal::WireType::k32Bit: + *os << " (I32): " << std::hex << std::showbase + << field.uint32_value() << std::dec << "\n"; + break; + } + break; + } + } + *os << " }\n"; + break; + } + default: + *os << " unknown field " << field.tag(); + switch (field.type()) { + case log_internal::WireType::kVarint: + *os << " (VARINT): " << std::hex << std::showbase + << field.uint64_value() << std::dec << "\n"; + break; + case log_internal::WireType::k64Bit: + *os << " (I64): " << std::hex << std::showbase + << field.uint64_value() << std::dec << "\n"; + break; + case log_internal::WireType::kLengthDelimited: + *os << " (LEN): \"" << absl::CHexEscape(field.string_value()) + << "\"\n"; + break; + case log_internal::WireType::k32Bit: + *os << " (I32): " << std::hex << std::showbase + << field.uint32_value() << std::dec << "\n"; + break; + } + break; + } + } + *os << " }\n" + << " stacktrace: \"" << absl::CHexEscape(entry.stacktrace()) << "\"\n" + << "}"; +} + +ABSL_NAMESPACE_END +} // namespace absl
diff --git a/absl/log/log_entry.h b/absl/log/log_entry.h index 7a55dfe..c566856 100644 --- a/absl/log/log_entry.h +++ b/absl/log/log_entry.h
@@ -25,6 +25,7 @@ #define ABSL_LOG_LOG_ENTRY_H_ #include <cstddef> +#include <ostream> #include <string> #include "absl/base/attributes.h" @@ -213,6 +214,7 @@ friend class log_internal::LogEntryTestPeer; friend class log_internal::LogMessage; + friend void PrintTo(const absl::LogEntry& entry, std::ostream* os); }; ABSL_NAMESPACE_END
diff --git a/absl/log/log_format_test.cc b/absl/log/log_format_test.cc index 6b7d1e5..9f1cc6b 100644 --- a/absl/log/log_format_test.cc +++ b/absl/log/log_format_test.cc
@@ -73,6 +73,7 @@ TEST(LogFormatTest, NoMessage) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const int log_line = __LINE__ + 1; auto do_log = [] { LOG(INFO); }; @@ -95,6 +96,7 @@ TYPED_TEST(CharLogFormatTest, Printable) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const TypeParam value = 'x'; auto comparison_stream = ComparisonStream(); @@ -112,6 +114,7 @@ TYPED_TEST(CharLogFormatTest, Unprintable) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); constexpr auto value = static_cast<TypeParam>(0xeeu); auto comparison_stream = ComparisonStream(); @@ -130,6 +133,7 @@ TEST(WideCharLogFormatTest, Printable) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send(AllOf(TextMessage(Eq("€")), ENCODED_MESSAGE(HasValues( @@ -142,6 +146,7 @@ TEST(WideCharLogFormatTest, Unprintable) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); // Using NEL (Next Line) Unicode character (U+0085). // It is encoded as "\xC2\x85" in UTF-8. @@ -163,6 +168,7 @@ TYPED_TEST(UnsignedIntLogFormatTest, Positive) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const TypeParam value = 224; auto comparison_stream = ComparisonStream(); @@ -181,6 +187,7 @@ TYPED_TEST(UnsignedIntLogFormatTest, BitfieldPositive) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const struct { TypeParam bits : 6; @@ -206,6 +213,7 @@ TYPED_TEST(SignedIntLogFormatTest, Positive) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const TypeParam value = 224; auto comparison_stream = ComparisonStream(); @@ -224,6 +232,7 @@ TYPED_TEST(SignedIntLogFormatTest, Negative) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const TypeParam value = -112; auto comparison_stream = ComparisonStream(); @@ -242,6 +251,7 @@ TYPED_TEST(SignedIntLogFormatTest, BitfieldPositive) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const struct { TypeParam bits : 6; @@ -261,6 +271,7 @@ TYPED_TEST(SignedIntLogFormatTest, BitfieldNegative) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const struct { TypeParam bits : 6; @@ -305,6 +316,7 @@ TYPED_TEST(UnsignedEnumLogFormatTest, Positive) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const TypeParam value = static_cast<TypeParam>(224); auto comparison_stream = ComparisonStream(); @@ -323,6 +335,7 @@ TYPED_TEST(UnsignedEnumLogFormatTest, BitfieldPositive) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const struct { TypeParam bits : 6; @@ -365,6 +378,7 @@ TYPED_TEST(SignedEnumLogFormatTest, Positive) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const TypeParam value = static_cast<TypeParam>(224); auto comparison_stream = ComparisonStream(); @@ -383,6 +397,7 @@ TYPED_TEST(SignedEnumLogFormatTest, Negative) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const TypeParam value = static_cast<TypeParam>(-112); auto comparison_stream = ComparisonStream(); @@ -401,6 +416,7 @@ TYPED_TEST(SignedEnumLogFormatTest, BitfieldPositive) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const struct { TypeParam bits : 6; @@ -420,6 +436,7 @@ TYPED_TEST(SignedEnumLogFormatTest, BitfieldNegative) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const struct { TypeParam bits : 6; @@ -441,6 +458,7 @@ TEST(FloatLogFormatTest, Positive) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const float value = 6.02e23f; auto comparison_stream = ComparisonStream(); @@ -458,6 +476,7 @@ TEST(FloatLogFormatTest, Negative) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const float value = -6.02e23f; auto comparison_stream = ComparisonStream(); @@ -475,6 +494,7 @@ TEST(FloatLogFormatTest, NegativeExponent) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const float value = 6.02e-23f; auto comparison_stream = ComparisonStream(); @@ -492,6 +512,7 @@ TEST(DoubleLogFormatTest, Positive) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const double value = 6.02e23; auto comparison_stream = ComparisonStream(); @@ -509,6 +530,7 @@ TEST(DoubleLogFormatTest, Negative) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const double value = -6.02e23; auto comparison_stream = ComparisonStream(); @@ -526,6 +548,7 @@ TEST(DoubleLogFormatTest, NegativeExponent) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const double value = 6.02e-23; auto comparison_stream = ComparisonStream(); @@ -548,6 +571,7 @@ TYPED_TEST(FloatingPointLogFormatTest, Zero) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const TypeParam value = 0.0; auto comparison_stream = ComparisonStream(); @@ -565,6 +589,7 @@ TYPED_TEST(FloatingPointLogFormatTest, Integer) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const TypeParam value = 1.0; auto comparison_stream = ComparisonStream(); @@ -582,6 +607,7 @@ TYPED_TEST(FloatingPointLogFormatTest, Infinity) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const TypeParam value = std::numeric_limits<TypeParam>::infinity(); auto comparison_stream = ComparisonStream(); @@ -600,6 +626,7 @@ TYPED_TEST(FloatingPointLogFormatTest, NegativeInfinity) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const TypeParam value = -std::numeric_limits<TypeParam>::infinity(); auto comparison_stream = ComparisonStream(); @@ -618,6 +645,7 @@ TYPED_TEST(FloatingPointLogFormatTest, NaN) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const TypeParam value = std::numeric_limits<TypeParam>::quiet_NaN(); auto comparison_stream = ComparisonStream(); @@ -635,6 +663,7 @@ TYPED_TEST(FloatingPointLogFormatTest, NegativeNaN) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const TypeParam value = std::copysign(std::numeric_limits<TypeParam>::quiet_NaN(), -1.0); @@ -671,6 +700,7 @@ TYPED_TEST(VoidPtrLogFormatTest, Null) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const TypeParam value = nullptr; auto comparison_stream = ComparisonStream(); @@ -688,6 +718,7 @@ TYPED_TEST(VoidPtrLogFormatTest, NonNull) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const TypeParam value = reinterpret_cast<TypeParam>(0xdeadbeefULL); auto comparison_stream = ComparisonStream(); @@ -715,6 +746,7 @@ TYPED_TEST(VolatilePtrLogFormatTest, Null) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const TypeParam value = nullptr; auto comparison_stream = ComparisonStream(); @@ -742,6 +774,7 @@ TYPED_TEST(VolatilePtrLogFormatTest, NonNull) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const TypeParam value = reinterpret_cast<TypeParam>(0xdeadbeefLL); auto comparison_stream = ComparisonStream(); @@ -777,6 +810,7 @@ TYPED_TEST(CharPtrLogFormatTest, Null) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); // Streaming `([cv] char *)nullptr` into a `std::ostream` is UB, and some C++ // standard library implementations choose to crash. We take measures to log @@ -797,6 +831,7 @@ TYPED_TEST(CharPtrLogFormatTest, NonNull) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); TypeParam data[] = {'v', 'a', 'l', 'u', 'e', '\0'}; TypeParam* const value = data; @@ -821,6 +856,7 @@ TYPED_TEST(WideCharPtrLogFormatTest, Null) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); TypeParam* const value = nullptr; @@ -834,6 +870,7 @@ TYPED_TEST(WideCharPtrLogFormatTest, NonNull) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); TypeParam data[] = {'v', 'a', 'l', 'u', 'e', '\0'}; TypeParam* const value = data; @@ -848,6 +885,7 @@ TEST(BoolLogFormatTest, True) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const bool value = true; auto comparison_stream = ComparisonStream(); @@ -866,6 +904,7 @@ TEST(BoolLogFormatTest, False) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const bool value = false; auto comparison_stream = ComparisonStream(); @@ -884,6 +923,7 @@ TEST(LogFormatTest, StringLiteral) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); auto comparison_stream = ComparisonStream(); comparison_stream << "value"; @@ -900,6 +940,7 @@ TEST(LogFormatTest, WideStringLiteral) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send(AllOf(TextMessage(Eq("value")), ENCODED_MESSAGE(HasValues(ElementsAre( @@ -911,6 +952,7 @@ TEST(LogFormatTest, CharArray) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); char value[] = "value"; auto comparison_stream = ComparisonStream(); @@ -929,6 +971,7 @@ TEST(LogFormatTest, WideCharArray) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); wchar_t value[] = L"value"; @@ -967,6 +1010,7 @@ TYPED_TEST(WideStringLogFormatTest, NonLiterals) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); TypeParam value = ABSL_LOG_INTERNAL_WIDE_LITERAL; absl::string_view utf8_value = GetUtf8TestString(); @@ -981,6 +1025,7 @@ TEST(WideStringLogFormatTest, StringView) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); std::wstring_view value = ABSL_LOG_INTERNAL_WIDE_LITERAL; absl::string_view utf8_value = GetUtf8TestString(); @@ -995,6 +1040,7 @@ TEST(WideStringLogFormatTest, Literal) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); absl::string_view utf8_value = GetUtf8TestString(); @@ -1011,6 +1057,7 @@ TYPED_TEST(WideStringLogFormatTest, IsolatedLowSurrogatesAreReplaced) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); TypeParam value = L"AAA \xDC00 BBB"; // NOLINTNEXTLINE(readability/utf8) @@ -1027,6 +1074,7 @@ TYPED_TEST(WideStringLogFormatTest, DISABLED_IsolatedHighSurrogatesAreReplaced) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); TypeParam value = L"AAA \xD800 BBB"; // NOLINTNEXTLINE(readability/utf8) @@ -1044,6 +1092,7 @@ TYPED_TEST(WideStringLogFormatTest, DISABLED_ConsecutiveHighSurrogatesAreReplaced) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); TypeParam value = L"AAA \xD800\xD800 BBB"; // NOLINTNEXTLINE(readability/utf8) @@ -1061,6 +1110,7 @@ TYPED_TEST(WideStringLogFormatTest, DISABLED_HighHighLowSurrogateSequencesAreReplaced) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); TypeParam value = L"AAA \xD800\xD800\xDC00 BBB"; // NOLINTNEXTLINE(readability/utf8) @@ -1078,6 +1128,7 @@ TYPED_TEST(WideStringLogFormatTest, DISABLED_TrailingHighSurrogatesAreReplaced) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); TypeParam value = L"AAA \xD800"; // NOLINTNEXTLINE(readability/utf8) @@ -1094,6 +1145,7 @@ TYPED_TEST(WideStringLogFormatTest, EmptyWideString) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); TypeParam value = L""; @@ -1121,6 +1173,7 @@ TEST(LogFormatTest, Custom) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); CustomClass value; auto comparison_stream = ComparisonStream(); @@ -1147,6 +1200,7 @@ TEST(LogFormatTest, CustomNonCopyable) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); CustomClassNonCopyable value; auto comparison_stream = ComparisonStream(); @@ -1174,6 +1228,7 @@ TEST(LogFormatTest, AbslStringifyExample) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); Point p; @@ -1205,6 +1260,7 @@ TEST(LogFormatTest, CustomWithAbslStringifyAndOstream) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); PointWithAbslStringifiyAndOstream p; @@ -1228,6 +1284,7 @@ TEST(LogFormatTest, AbslStringifyStreamsNothing) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); PointStreamsNothing p; @@ -1254,6 +1311,7 @@ TEST(LogFormatTest, AbslStringifyMultipleAppend) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); PointMultipleAppend p; @@ -1269,6 +1327,7 @@ TEST(ManipulatorLogFormatTest, BoolAlphaTrue) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const bool value = true; auto comparison_stream = ComparisonStream(); @@ -1293,6 +1352,7 @@ TEST(ManipulatorLogFormatTest, BoolAlphaFalse) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const bool value = false; auto comparison_stream = ComparisonStream(); @@ -1317,6 +1377,7 @@ TEST(ManipulatorLogFormatTest, ShowPoint) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const double value = 77.0; auto comparison_stream = ComparisonStream(); @@ -1341,6 +1402,7 @@ TEST(ManipulatorLogFormatTest, ShowPos) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const int value = 77; auto comparison_stream = ComparisonStream(); @@ -1364,6 +1426,7 @@ TEST(ManipulatorLogFormatTest, UppercaseFloat) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const double value = 7.7e7; auto comparison_stream = ComparisonStream(); @@ -1388,6 +1451,7 @@ TEST(ManipulatorLogFormatTest, Hex) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const int value = 0x77; auto comparison_stream = ComparisonStream(); @@ -1405,6 +1469,7 @@ TEST(ManipulatorLogFormatTest, Oct) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const int value = 077; auto comparison_stream = ComparisonStream(); @@ -1423,6 +1488,7 @@ TEST(ManipulatorLogFormatTest, Dec) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const int value = 77; auto comparison_stream = ComparisonStream(); @@ -1440,6 +1506,7 @@ TEST(ManipulatorLogFormatTest, ShowbaseHex) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const int value = 0x77; auto comparison_stream = ComparisonStream(); @@ -1466,6 +1533,7 @@ TEST(ManipulatorLogFormatTest, ShowbaseOct) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const int value = 077; auto comparison_stream = ComparisonStream(); @@ -1491,6 +1559,7 @@ TEST(ManipulatorLogFormatTest, UppercaseHex) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const int value = 0xbeef; auto comparison_stream = ComparisonStream(); @@ -1518,6 +1587,7 @@ TEST(ManipulatorLogFormatTest, FixedFloat) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const double value = 7.7e7; auto comparison_stream = ComparisonStream(); @@ -1535,6 +1605,7 @@ TEST(ManipulatorLogFormatTest, ScientificFloat) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const double value = 7.7e7; auto comparison_stream = ComparisonStream(); @@ -1558,6 +1629,7 @@ #else TEST(ManipulatorLogFormatTest, FixedAndScientificFloat) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const double value = 7.7e7; auto comparison_stream = ComparisonStream(); @@ -1591,6 +1663,7 @@ #else TEST(ManipulatorLogFormatTest, HexfloatFloat) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const double value = 7.7e7; auto comparison_stream = ComparisonStream(); @@ -1612,6 +1685,7 @@ TEST(ManipulatorLogFormatTest, DefaultFloatFloat) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const double value = 7.7e7; auto comparison_stream = ComparisonStream(); @@ -1629,6 +1703,7 @@ TEST(ManipulatorLogFormatTest, Ends) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); auto comparison_stream = ComparisonStream(); comparison_stream << std::ends; @@ -1645,6 +1720,7 @@ TEST(ManipulatorLogFormatTest, Endl) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); auto comparison_stream = ComparisonStream(); comparison_stream << std::endl; @@ -1662,6 +1738,7 @@ TEST(ManipulatorLogFormatTest, SetIosFlags) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const int value = 0x77; auto comparison_stream = ComparisonStream(); @@ -1691,6 +1768,7 @@ TEST(ManipulatorLogFormatTest, SetBase) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const int value = 0x77; auto comparison_stream = ComparisonStream(); @@ -1715,6 +1793,7 @@ TEST(ManipulatorLogFormatTest, SetPrecision) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const double value = 6.022140857e23; auto comparison_stream = ComparisonStream(); @@ -1736,6 +1815,7 @@ TEST(ManipulatorLogFormatTest, SetPrecisionOverflow) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const double value = 6.022140857e23; auto comparison_stream = ComparisonStream(); @@ -1753,6 +1833,7 @@ TEST(ManipulatorLogFormatTest, SetW) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const int value = 77; auto comparison_stream = ComparisonStream(); @@ -1774,6 +1855,7 @@ TEST(ManipulatorLogFormatTest, Left) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const int value = -77; auto comparison_stream = ComparisonStream(); @@ -1791,6 +1873,7 @@ TEST(ManipulatorLogFormatTest, Right) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const int value = -77; auto comparison_stream = ComparisonStream(); @@ -1808,6 +1891,7 @@ TEST(ManipulatorLogFormatTest, Internal) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const int value = -77; auto comparison_stream = ComparisonStream(); @@ -1825,6 +1909,7 @@ TEST(ManipulatorLogFormatTest, SetFill) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); const int value = 77; auto comparison_stream = ComparisonStream(); @@ -1851,6 +1936,7 @@ TEST(ManipulatorLogFormatTest, FromCustom) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); FromCustomClass value; auto comparison_stream = ComparisonStream(); @@ -1873,6 +1959,7 @@ TEST(ManipulatorLogFormatTest, CustomClassStreamsNothing) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); StreamsNothing value; auto comparison_stream = ComparisonStream(); @@ -1900,6 +1987,7 @@ TEST(ManipulatorLogFormatTest, IOManipsDoNotAffectAbslStringify) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); PointPercentV p; @@ -1915,6 +2003,7 @@ TEST(StructuredLoggingOverflowTest, TruncatesStrings) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); // This message is too long and should be truncated to some unspecified size // no greater than the buffer size but not too much less either. It should be @@ -1937,6 +2026,7 @@ TEST(StructuredLoggingOverflowTest, TruncatesWideStrings) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); // This message is too long and should be truncated to some unspecified size // no greater than the buffer size but not too much less either. It should be @@ -1967,6 +2057,7 @@ TEST(StructuredLoggingOverflowTest, TruncatesInsertionOperators) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); // This message is too long and should be truncated to some unspecified size // no greater than the buffer size but not too much less either. It should be @@ -2018,6 +2109,7 @@ // sizes. To put any data in the field we need a fifth byte. { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send(AllOf(ENCODED_MESSAGE(HasOneStrThat( AllOf(SizeIs(longest_fit), Each(Eq('x'))))), @@ -2028,6 +2120,7 @@ } { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send(AllOf(ENCODED_MESSAGE(HasOneStrThat( AllOf(SizeIs(longest_fit - 1), Each(Eq('x'))))), @@ -2038,6 +2131,7 @@ } { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send(AllOf(ENCODED_MESSAGE(HasOneStrThat( AllOf(SizeIs(longest_fit - 2), Each(Eq('x'))))), @@ -2048,6 +2142,7 @@ } { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send(AllOf(ENCODED_MESSAGE(HasOneStrThat( AllOf(SizeIs(longest_fit - 3), Each(Eq('x'))))), @@ -2058,6 +2153,7 @@ } { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send(AllOf(ENCODED_MESSAGE(HasOneStrAndOneLiteralThat( AllOf(SizeIs(longest_fit - 4), Each(Eq('x'))), @@ -2070,6 +2166,7 @@ } { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL( test_sink, Send(AllOf(ENCODED_MESSAGE(HasOneStrAndOneLiteralThat( @@ -2087,6 +2184,7 @@ // sizes. To put any data in the field we need a fifth byte. { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send(AllOf(ENCODED_MESSAGE(HasOneStrThat( AllOf(SizeIs(longest_fit), Each(Eq('x'))))), @@ -2097,6 +2195,7 @@ } { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send(AllOf(ENCODED_MESSAGE(HasOneStrThat( AllOf(SizeIs(longest_fit - 1), Each(Eq('x'))))), @@ -2108,6 +2207,7 @@ } { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send(AllOf(ENCODED_MESSAGE(HasOneStrThat( AllOf(SizeIs(longest_fit - 2), Each(Eq('x'))))), @@ -2119,6 +2219,7 @@ } { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send(AllOf(ENCODED_MESSAGE(HasOneStrThat( AllOf(SizeIs(longest_fit - 3), Each(Eq('x'))))), @@ -2130,6 +2231,7 @@ } { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send(AllOf(ENCODED_MESSAGE(HasOneStrThat( AllOf(SizeIs(longest_fit - 4), Each(Eq('x'))))), @@ -2143,6 +2245,7 @@ } { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL( test_sink, Send(AllOf(ENCODED_MESSAGE(HasTwoStrsThat(
diff --git a/absl/log/log_modifier_methods_test.cc b/absl/log/log_modifier_methods_test.cc index 4cee0c0..7893557 100644 --- a/absl/log/log_modifier_methods_test.cc +++ b/absl/log/log_modifier_methods_test.cc
@@ -60,6 +60,7 @@ TEST(TailCallsModifiesTest, AtLocationFileLine) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL( test_sink, @@ -89,6 +90,7 @@ TEST(TailCallsModifiesTest, NoPrefix) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send(AllOf(Prefix(IsFalse()), TextPrefix(IsEmpty()), TextMessageWithPrefix(Eq("hello world"))))); @@ -99,6 +101,7 @@ TEST(TailCallsModifiesTest, NoPrefixNoMessageNoShirtNoShoesNoService) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send(AllOf(Prefix(IsFalse()), TextPrefix(IsEmpty()), @@ -110,6 +113,7 @@ TEST(TailCallsModifiesTest, WithVerbosity) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send(Verbosity(Eq(2)))); @@ -119,6 +123,7 @@ TEST(TailCallsModifiesTest, WithVerbosityNoVerbosity) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send(Verbosity(Eq(absl::LogEntry::kNoVerbosityLevel)))); @@ -130,6 +135,7 @@ TEST(TailCallsModifiesTest, WithTimestamp) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send(Timestamp(Eq(absl::UnixEpoch())))); @@ -139,6 +145,7 @@ TEST(TailCallsModifiesTest, WithThreadID) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send(AllOf(ThreadID(Eq(absl::LogEntry::tid_t{1234}))))); @@ -157,6 +164,7 @@ } forwarding_sink; absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL( test_sink, @@ -185,6 +193,7 @@ TEST(TailCallsModifiesTest, WithPerror) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL( test_sink, @@ -211,6 +220,7 @@ { absl::ScopedMockLog test_sink( absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); auto do_log = [&test_sink] { LOG(QFATAL).ToSinkOnly(&test_sink.UseAsLocalSink()) << "hello world";
diff --git a/absl/log/log_streamer_test.cc b/absl/log/log_streamer_test.cc index 4fe88e9..f226fef 100644 --- a/absl/log/log_streamer_test.cc +++ b/absl/log/log_streamer_test.cc
@@ -66,6 +66,7 @@ TEST(LogStreamerTest, LogInfoStreamer) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL( test_sink, @@ -87,6 +88,7 @@ TEST(LogStreamerTest, LogWarningStreamer) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL( test_sink, @@ -109,6 +111,7 @@ TEST(LogStreamerTest, LogErrorStreamer) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL( test_sink, @@ -133,6 +136,7 @@ EXPECT_EXIT( { absl::ScopedMockLog test_sink; + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send) .Times(AnyNumber()) @@ -164,6 +168,7 @@ #ifdef NDEBUG TEST(LogStreamerTest, LogDebugFatalStreamer) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL( test_sink, @@ -188,6 +193,7 @@ EXPECT_EXIT( { absl::ScopedMockLog test_sink; + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send) .Times(AnyNumber()) @@ -218,6 +224,7 @@ TEST(LogStreamerTest, LogStreamer) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL( test_sink, @@ -244,6 +251,7 @@ EXPECT_EXIT( { absl::ScopedMockLog test_sink; + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send) .Times(AnyNumber()) @@ -275,6 +283,7 @@ TEST(LogStreamerTest, PassedByReference) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL( test_sink, @@ -291,6 +300,7 @@ TEST(LogStreamerTest, StoredAsLocal) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); auto streamer = absl::LogInfoStreamer("path/file.cc", 1234); WriteToStream("foo", &streamer.stream()); @@ -328,6 +338,7 @@ TEST(LogStreamerTest, LogsEmptyLine) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL(test_sink, Send(AllOf(SourceFilename(Eq("path/file.cc")), SourceLine(Eq(1234)), TextMessage(Eq("")), @@ -345,8 +356,7 @@ EXPECT_EXIT( { absl::ScopedMockLog test_sink; - - EXPECT_CALL(test_sink, Log) + EXPECT_CALL(test_sink, Send) .Times(AnyNumber()) .WillRepeatedly(DeathTestUnexpectedLogging()); @@ -368,6 +378,7 @@ TEST(LogStreamerTest, MoveConstruction) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); EXPECT_CALL( test_sink, @@ -389,6 +400,7 @@ TEST(LogStreamerTest, MoveAssignment) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); testing::InSequence seq; EXPECT_CALL( @@ -423,6 +435,7 @@ TEST(LogStreamerTest, CorrectDefaultFlags) { absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(test_sink, Send).Times(0); // The `boolalpha` and `showbase` flags should be set by default, to match // `LOG`.
diff --git a/absl/log/scoped_mock_log.h b/absl/log/scoped_mock_log.h index a383066..9700873 100644 --- a/absl/log/scoped_mock_log.h +++ b/absl/log/scoped_mock_log.h
@@ -160,7 +160,13 @@ // from the log message text, log message path and log message severity. // // If no expectations are specified for this mock, the default action is to - // forward the call to the `Log` mock. + // forward the call to the `Log` mock. Tests using `Send` are advised to call + // + // `EXPECT_CALL(sink, Send).Times(0);` + // + // prior to specifying other expectations to suppress forwarding to `Log`. + // That way, unexpected calls show up as calls to `Send` with complete data + // and metadata for easier debugging. MOCK_METHOD(void, Send, (const absl::LogEntry&)); // Implements the mock method:
diff --git a/absl/log/structured_test.cc b/absl/log/structured_test.cc index 9fe0756..cde8199 100644 --- a/absl/log/structured_test.cc +++ b/absl/log/structured_test.cc
@@ -50,6 +50,7 @@ stream << LoggingDefaults << absl::LogAsLiteral(not_a_literal); absl::ScopedMockLog sink; + EXPECT_CALL(sink, Send).Times(0); EXPECT_CALL(sink, Send(AllOf(TextMessage(MatchesOstream(stream)), TextMessage(Eq("hello world")),
diff --git a/absl/profiling/internal/sample_recorder.h b/absl/profiling/internal/sample_recorder.h index 84843fd..88a4b27 100644 --- a/absl/profiling/internal/sample_recorder.h +++ b/absl/profiling/internal/sample_recorder.h
@@ -130,7 +130,7 @@ template <typename T> SampleRecorder<T>::SampleRecorder() : dropped_samples_(0), size_estimate_(0), all_(nullptr), dispose_(nullptr) { - absl::MutexLock l(&graveyard_.init_mu); + absl::MutexLock l(graveyard_.init_mu); graveyard_.dead = &graveyard_; } @@ -159,8 +159,8 @@ dispose(*sample); } - absl::MutexLock graveyard_lock(&graveyard_.init_mu); - absl::MutexLock sample_lock(&sample->init_mu); + absl::MutexLock graveyard_lock(graveyard_.init_mu); + absl::MutexLock sample_lock(sample->init_mu); sample->dead = graveyard_.dead; graveyard_.dead = sample; } @@ -168,7 +168,7 @@ template <typename T> template <typename... Targs> T* SampleRecorder<T>::PopDead(Targs... args) { - absl::MutexLock graveyard_lock(&graveyard_.init_mu); + absl::MutexLock graveyard_lock(graveyard_.init_mu); // The list is circular, so eventually it collapses down to // graveyard_.dead == &graveyard_ @@ -176,7 +176,7 @@ T* sample = graveyard_.dead; if (sample == &graveyard_) return nullptr; - absl::MutexLock sample_lock(&sample->init_mu); + absl::MutexLock sample_lock(sample->init_mu); graveyard_.dead = sample->dead; sample->dead = nullptr; sample->PrepareForSampling(std::forward<Targs>(args)...); @@ -198,7 +198,7 @@ // Resurrection failed. Hire a new warlock. sample = new T(); { - absl::MutexLock sample_lock(&sample->init_mu); + absl::MutexLock sample_lock(sample->init_mu); // If flag initialization happens to occur (perhaps in another thread) // while in this block, it will lock `graveyard_` which is usually always // locked before any sample. This will appear as a lock inversion. @@ -226,7 +226,7 @@ const std::function<void(const T& stack)>& f) { T* s = all_.load(std::memory_order_acquire); while (s != nullptr) { - absl::MutexLock l(&s->init_mu); + absl::MutexLock l(s->init_mu); if (s->dead == nullptr) { f(*s); }
diff --git a/absl/random/internal/BUILD.bazel b/absl/random/internal/BUILD.bazel index a9adea3..1a3fef8 100644 --- a/absl/random/internal/BUILD.bazel +++ b/absl/random/internal/BUILD.bazel
@@ -802,6 +802,7 @@ linkopts = ABSL_DEFAULT_LINKOPTS, tags = [ "benchmark", + "no_test_ios_sim_arm64", "no_test_ios_x86_64", "no_test_loonix", # Crashing. "no_test_wasm",
diff --git a/absl/random/internal/entropy_pool.cc b/absl/random/internal/entropy_pool.cc index fa47d0d..1386700 100644 --- a/absl/random/internal/entropy_pool.cc +++ b/absl/random/internal/entropy_pool.cc
@@ -55,7 +55,7 @@ RandenTraits::kCapacityBytes / sizeof(uint32_t); void Init(absl::Span<const uint32_t> data) { - SpinLockHolder l(&mu_); // Always uncontested. + SpinLockHolder l(mu_); // Always uncontested. std::copy(data.begin(), data.end(), std::begin(state_)); next_ = kState; } @@ -84,7 +84,7 @@ }; void RandenPoolEntry::Fill(uint8_t* out, size_t bytes) { - SpinLockHolder l(&mu_); + SpinLockHolder l(mu_); while (bytes > 0) { MaybeRefill(); size_t remaining = available() * sizeof(state_[0]);
diff --git a/absl/random/internal/entropy_pool_test.cc b/absl/random/internal/entropy_pool_test.cc index 89ea72f..7739f19 100644 --- a/absl/random/internal/entropy_pool_test.cc +++ b/absl/random/internal/entropy_pool_test.cc
@@ -44,7 +44,7 @@ threads.emplace_back([&]() { std::vector<result_type> v(kValuesPerThread); GetEntropyFromRandenPool(v.data(), sizeof(result_type) * v.size()); - absl::MutexLock l(&mu); + absl::MutexLock l(mu); data.push_back(std::move(v)); }); }
diff --git a/absl/random/internal/nonsecure_base_test.cc b/absl/random/internal/nonsecure_base_test.cc index 6b6f2d5..6e3e712 100644 --- a/absl/random/internal/nonsecure_base_test.cc +++ b/absl/random/internal/nonsecure_base_test.cc
@@ -214,7 +214,7 @@ std::vector<result_type> v(kValuesPerThread); std::generate(v.begin(), v.end(), [&]() { return gen(); }); - absl::MutexLock l(&mu); + absl::MutexLock l(mu); data.push_back(std::move(v)); }); }
diff --git a/absl/strings/internal/cord_internal.h b/absl/strings/internal/cord_internal.h index cf1f703..5045811 100644 --- a/absl/strings/internal/cord_internal.h +++ b/absl/strings/internal/cord_internal.h
@@ -915,8 +915,6 @@ inline void CordRep::Unref(CordRep* rep) { assert(rep != nullptr); - // Expect refcount to be 0. Avoiding the cost of an atomic decrement should - // typically outweigh the cost of an extra branch checking for ref == 1. if (ABSL_PREDICT_FALSE(!rep->refcount.DecrementExpectHighRefcount())) { Destroy(rep); }
diff --git a/absl/strings/internal/cordz_handle.cc b/absl/strings/internal/cordz_handle.cc index 53d5f52..a4f47f0 100644 --- a/absl/strings/internal/cordz_handle.cc +++ b/absl/strings/internal/cordz_handle.cc
@@ -54,7 +54,7 @@ CordzHandle::CordzHandle(bool is_snapshot) : is_snapshot_(is_snapshot) { Queue& global_queue = GlobalQueue(); if (is_snapshot) { - MutexLock lock(&global_queue.mutex); + MutexLock lock(global_queue.mutex); CordzHandle* dq_tail = global_queue.dq_tail.load(std::memory_order_acquire); if (dq_tail != nullptr) { dq_prev_ = dq_tail; @@ -69,7 +69,7 @@ if (is_snapshot_) { std::vector<CordzHandle*> to_delete; { - MutexLock lock(&global_queue.mutex); + MutexLock lock(global_queue.mutex); CordzHandle* next = dq_next_; if (dq_prev_ == nullptr) { // We were head of the queue, delete every CordzHandle until we reach @@ -103,7 +103,7 @@ if (handle) { Queue& queue = GlobalQueue(); if (!handle->SafeToDelete()) { - MutexLock lock(&queue.mutex); + MutexLock lock(queue.mutex); CordzHandle* dq_tail = queue.dq_tail.load(std::memory_order_acquire); if (dq_tail != nullptr) { handle->dq_prev_ = dq_tail; @@ -119,7 +119,7 @@ std::vector<const CordzHandle*> CordzHandle::DiagnosticsGetDeleteQueue() { std::vector<const CordzHandle*> handles; Queue& global_queue = GlobalQueue(); - MutexLock lock(&global_queue.mutex); + MutexLock lock(global_queue.mutex); CordzHandle* dq_tail = global_queue.dq_tail.load(std::memory_order_acquire); for (const CordzHandle* p = dq_tail; p; p = p->dq_prev_) { handles.push_back(p); @@ -134,7 +134,7 @@ if (handle->is_snapshot_) return false; bool snapshot_found = false; Queue& global_queue = GlobalQueue(); - MutexLock lock(&global_queue.mutex); + MutexLock lock(global_queue.mutex); for (const CordzHandle* p = global_queue.dq_tail; p; p = p->dq_prev_) { if (p == handle) return !snapshot_found; if (p == this) snapshot_found = true; @@ -151,7 +151,7 @@ } Queue& global_queue = GlobalQueue(); - MutexLock lock(&global_queue.mutex); + MutexLock lock(global_queue.mutex); for (const CordzHandle* p = dq_next_; p != nullptr; p = p->dq_next_) { if (!p->is_snapshot()) { handles.push_back(p);
diff --git a/absl/strings/internal/cordz_info.cc b/absl/strings/internal/cordz_info.cc index 4baaecd..a916c0c 100644 --- a/absl/strings/internal/cordz_info.cc +++ b/absl/strings/internal/cordz_info.cc
@@ -327,7 +327,7 @@ } void CordzInfo::Track() { - SpinLockHolder l(&list_->mutex); + SpinLockHolder l(list_->mutex); CordzInfo* const head = list_->head.load(std::memory_order_acquire); if (head != nullptr) { @@ -340,7 +340,7 @@ void CordzInfo::Untrack() { ODRCheck(); { - SpinLockHolder l(&list_->mutex); + SpinLockHolder l(list_->mutex); CordzInfo* const head = list_->head.load(std::memory_order_acquire); CordzInfo* const next = ci_next_.load(std::memory_order_acquire); @@ -370,7 +370,7 @@ // We are likely part of a snapshot, extend the life of the CordRep { - absl::MutexLock lock(&mutex_); + absl::MutexLock lock(mutex_); if (rep_) CordRep::Ref(rep_); } CordzHandle::Delete(this); @@ -378,14 +378,14 @@ void CordzInfo::Lock(MethodIdentifier method) ABSL_EXCLUSIVE_LOCK_FUNCTION(mutex_) { - mutex_.Lock(); + mutex_.lock(); update_tracker_.LossyAdd(method); assert(rep_); } void CordzInfo::Unlock() ABSL_UNLOCK_FUNCTION(mutex_) { bool tracked = rep_ != nullptr; - mutex_.Unlock(); + mutex_.unlock(); if (!tracked) { Untrack(); }
diff --git a/absl/strings/internal/cordz_info.h b/absl/strings/internal/cordz_info.h index 0091fa2..578aa59 100644 --- a/absl/strings/internal/cordz_info.h +++ b/absl/strings/internal/cordz_info.h
@@ -290,7 +290,7 @@ inline void CordzInfo::UnsafeSetCordRep(CordRep* rep) { rep_ = rep; } inline CordRep* CordzInfo::RefCordRep() const ABSL_LOCKS_EXCLUDED(mutex_) { - MutexLock lock(&mutex_); + MutexLock lock(mutex_); return rep_ ? CordRep::Ref(rep_) : nullptr; }
diff --git a/absl/strings/string_view.h b/absl/strings/string_view.h index eca5404..1dc04c5 100644 --- a/absl/strings/string_view.h +++ b/absl/strings/string_view.h
@@ -749,8 +749,8 @@ // // Like `s.substr(pos, n)`, but clips `pos` to an upper bound of `s.size()`. // Provided because std::string_view::substr throws if `pos > size()` -inline string_view ClippedSubstr(string_view s, size_t pos, - size_t n = string_view::npos) { +inline string_view ClippedSubstr(string_view s ABSL_ATTRIBUTE_LIFETIME_BOUND, + size_t pos, size_t n = string_view::npos) { pos = (std::min)(pos, static_cast<size_t>(s.size())); return s.substr(pos, n); }
diff --git a/absl/synchronization/barrier.cc b/absl/synchronization/barrier.cc index 0dfd795..f5dad22 100644 --- a/absl/synchronization/barrier.cc +++ b/absl/synchronization/barrier.cc
@@ -26,7 +26,7 @@ } bool Barrier::Block() { - MutexLock l(&this->lock_); + MutexLock l(this->lock_); this->num_to_block_--; if (this->num_to_block_ < 0) {
diff --git a/absl/synchronization/barrier_test.cc b/absl/synchronization/barrier_test.cc index bfc6cb1..2aed272 100644 --- a/absl/synchronization/barrier_test.cc +++ b/absl/synchronization/barrier_test.cc
@@ -37,7 +37,7 @@ } // Increment the counter. - absl::MutexLock lock(&mutex); + absl::MutexLock lock(mutex); ++counter; }; @@ -57,7 +57,7 @@ // The counter should still be zero since no thread should have // been able to pass the barrier yet. { - absl::MutexLock lock(&mutex); + absl::MutexLock lock(mutex); EXPECT_EQ(counter, 0); } @@ -70,6 +70,6 @@ } // All threads should now have incremented the counter. - absl::MutexLock lock(&mutex); + absl::MutexLock lock(mutex); EXPECT_EQ(counter, kNumThreads); }
diff --git a/absl/synchronization/blocking_counter.cc b/absl/synchronization/blocking_counter.cc index a530baf..9468469 100644 --- a/absl/synchronization/blocking_counter.cc +++ b/absl/synchronization/blocking_counter.cc
@@ -42,7 +42,7 @@ "BlockingCounter::DecrementCount() called too many times"); if (count == 0) { base_internal::TraceSignal(this, TraceObjectKind()); - MutexLock l(&lock_); + MutexLock l(lock_); done_ = true; return true; } @@ -52,7 +52,7 @@ void BlockingCounter::Wait() { base_internal::TraceWait(this, TraceObjectKind()); { - MutexLock l(&this->lock_); + MutexLock l(this->lock_); // only one thread may call Wait(). To support more than one thread, // implement a counter num_to_exit, like in the Barrier class.
diff --git a/absl/synchronization/internal/create_thread_identity.cc b/absl/synchronization/internal/create_thread_identity.cc index 2ec8075..0b0f920 100644 --- a/absl/synchronization/internal/create_thread_identity.cc +++ b/absl/synchronization/internal/create_thread_identity.cc
@@ -60,7 +60,7 @@ // association state in this case. base_internal::ClearCurrentThreadIdentity(); { - base_internal::SpinLockHolder l(&freelist_lock); + base_internal::SpinLockHolder l(freelist_lock); identity->next = thread_identity_freelist; thread_identity_freelist = identity; } @@ -108,7 +108,7 @@ { // Re-use a previously released object if possible. - base_internal::SpinLockHolder l(&freelist_lock); + base_internal::SpinLockHolder l(freelist_lock); if (thread_identity_freelist) { identity = thread_identity_freelist; // Take list-head. thread_identity_freelist = thread_identity_freelist->next;
diff --git a/absl/synchronization/internal/graphcycles.cc b/absl/synchronization/internal/graphcycles.cc index e332520..f58fb0a 100644 --- a/absl/synchronization/internal/graphcycles.cc +++ b/absl/synchronization/internal/graphcycles.cc
@@ -58,7 +58,7 @@ ABSL_CONST_INIT static base_internal::LowLevelAlloc::Arena* arena; static void InitArenaIfNecessary() { - base_internal::SpinLockHolder l(&arena_mu); + base_internal::SpinLockHolder l(arena_mu); if (arena == nullptr) { arena = base_internal::LowLevelAlloc::NewArena(0); }
diff --git a/absl/synchronization/internal/thread_pool.h b/absl/synchronization/internal/thread_pool.h index 5eb0bb6..f87adf6 100644 --- a/absl/synchronization/internal/thread_pool.h +++ b/absl/synchronization/internal/thread_pool.h
@@ -46,7 +46,7 @@ ~ThreadPool() { { - absl::MutexLock l(&mu_); + absl::MutexLock l(mu_); for (size_t i = 0; i < threads_.size(); i++) { queue_.push(nullptr); // Shutdown signal. } @@ -59,7 +59,7 @@ // Schedule a function to be run on a ThreadPool thread immediately. void Schedule(absl::AnyInvocable<void()> func) { assert(func != nullptr); - absl::MutexLock l(&mu_); + absl::MutexLock l(mu_); queue_.push(std::move(func)); } @@ -72,7 +72,7 @@ while (true) { absl::AnyInvocable<void()> func; { - absl::MutexLock l(&mu_); + absl::MutexLock l(mu_); mu_.Await(absl::Condition(this, &ThreadPool::WorkAvailable)); func = std::move(queue_.front()); queue_.pop();
diff --git a/absl/synchronization/lifetime_test.cc b/absl/synchronization/lifetime_test.cc index 4c4cff6..603234a 100644 --- a/absl/synchronization/lifetime_test.cc +++ b/absl/synchronization/lifetime_test.cc
@@ -148,12 +148,12 @@ // before the constructors of either grab_lock or check_still_locked are run.) extern absl::Mutex const_init_sanity_mutex; OnConstruction grab_lock([]() ABSL_NO_THREAD_SAFETY_ANALYSIS { - const_init_sanity_mutex.Lock(); + const_init_sanity_mutex.lock(); }); ABSL_CONST_INIT absl::Mutex const_init_sanity_mutex(absl::kConstInit); OnConstruction check_still_locked([]() ABSL_NO_THREAD_SAFETY_ANALYSIS { const_init_sanity_mutex.AssertHeld(); - const_init_sanity_mutex.Unlock(); + const_init_sanity_mutex.unlock(); }); #endif // defined(__clang__) || !(defined(_MSC_VER) && _MSC_VER > 1900)
diff --git a/absl/synchronization/mutex.cc b/absl/synchronization/mutex.cc index 4c862fc..1d58582 100644 --- a/absl/synchronization/mutex.cc +++ b/absl/synchronization/mutex.cc
@@ -1223,9 +1223,8 @@ } static GraphId GetGraphId(Mutex* mu) ABSL_LOCKS_EXCLUDED(deadlock_graph_mu) { - deadlock_graph_mu.lock(); + base_internal::SpinLockHolder l(deadlock_graph_mu); GraphId id = GetGraphIdLocked(mu); - deadlock_graph_mu.unlock(); return id; } @@ -1386,7 +1385,7 @@ SynchLocksHeld* all_locks = Synch_GetAllLocks(); - absl::base_internal::SpinLockHolder lock(&deadlock_graph_mu); + absl::base_internal::SpinLockHolder lock(deadlock_graph_mu); const GraphId mu_id = GetGraphIdLocked(mu); if (all_locks->n == 0) { @@ -2761,7 +2760,7 @@ void ReleasableMutexLock::Release() { ABSL_RAW_CHECK(this->mu_ != nullptr, "ReleasableMutexLock::Release may only be called once"); - this->mu_->Unlock(); + this->mu_->unlock(); this->mu_ = nullptr; }
diff --git a/absl/synchronization/mutex.h b/absl/synchronization/mutex.h index 110c220..781135b 100644 --- a/absl/synchronization/mutex.h +++ b/absl/synchronization/mutex.h
@@ -293,12 +293,12 @@ // These methods may be used (along with the complementary `Reader*()` // methods) to distinguish simple exclusive `Mutex` usage (`Lock()`, // etc.) from reader/writer lock usage. - void WriterLock() ABSL_EXCLUSIVE_LOCK_FUNCTION() { this->lock(); } + void WriterLock() ABSL_EXCLUSIVE_LOCK_FUNCTION() { lock(); } - void WriterUnlock() ABSL_UNLOCK_FUNCTION() { this->unlock(); } + void WriterUnlock() ABSL_UNLOCK_FUNCTION() { unlock(); } [[nodiscard]] bool WriterTryLock() ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(true) { - return this->try_lock(); + return try_lock(); } // --------------------------------------------------------------------------- @@ -587,7 +587,7 @@ // Class Foo { // public: // Foo::Bar* Baz() { -// MutexLock lock(&mu_); +// MutexLock lock(mu_); // ... // return bar; // } @@ -599,32 +599,42 @@ public: // Constructors - // Calls `mu->Lock()` and returns when that call returns. That is, `*mu` is + // Calls `mu.lock()` and returns when that call returns. That is, `mu` is + // guaranteed to be locked when this object is constructed. + explicit MutexLock(Mutex& mu ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this)) + ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) + : mu_(mu) { + this->mu_.lock(); + } + + // Calls `mu->lock()` and returns when that call returns. That is, `*mu` is // guaranteed to be locked when this object is constructed. Requires that // `mu` be dereferenceable. explicit MutexLock(Mutex* absl_nonnull mu) ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) - : mu_(mu) { - this->mu_->Lock(); - } + : MutexLock(*mu) {} - // Like above, but calls `mu->LockWhen(cond)` instead. That is, in addition to + // Like above, but calls `mu.LockWhen(cond)` instead. That is, in addition to // the above, the condition given by `cond` is also guaranteed to hold when // this object is constructed. + explicit MutexLock(Mutex& mu ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this), + const Condition& cond) ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) + : mu_(mu) { + this->mu_.LockWhen(cond); + } + explicit MutexLock(Mutex* absl_nonnull mu, const Condition& cond) ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) - : mu_(mu) { - this->mu_->LockWhen(cond); - } + : MutexLock(*mu, cond) {} MutexLock(const MutexLock&) = delete; // NOLINT(runtime/mutex) MutexLock(MutexLock&&) = delete; // NOLINT(runtime/mutex) MutexLock& operator=(const MutexLock&) = delete; MutexLock& operator=(MutexLock&&) = delete; - ~MutexLock() ABSL_UNLOCK_FUNCTION() { this->mu_->Unlock(); } + ~MutexLock() ABSL_UNLOCK_FUNCTION() { this->mu_.unlock(); } private: - Mutex* absl_nonnull const mu_; + Mutex& mu_; }; // ReaderMutexLock @@ -633,26 +643,34 @@ // releases a shared lock on a `Mutex` via RAII. class ABSL_SCOPED_LOCKABLE ReaderMutexLock { public: - explicit ReaderMutexLock(Mutex* absl_nonnull mu) ABSL_SHARED_LOCK_FUNCTION(mu) + explicit ReaderMutexLock(Mutex& mu ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this)) + ABSL_SHARED_LOCK_FUNCTION(mu) : mu_(mu) { - mu->ReaderLock(); + mu.ReaderLock(); + } + + explicit ReaderMutexLock(Mutex* absl_nonnull mu) ABSL_SHARED_LOCK_FUNCTION(mu) + : ReaderMutexLock(*mu) {} + + explicit ReaderMutexLock(Mutex& mu ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this), + const Condition& cond) ABSL_SHARED_LOCK_FUNCTION(mu) + : mu_(mu) { + mu.ReaderLockWhen(cond); } explicit ReaderMutexLock(Mutex* absl_nonnull mu, const Condition& cond) ABSL_SHARED_LOCK_FUNCTION(mu) - : mu_(mu) { - mu->ReaderLockWhen(cond); - } + : ReaderMutexLock(*mu, cond) {} ReaderMutexLock(const ReaderMutexLock&) = delete; ReaderMutexLock(ReaderMutexLock&&) = delete; ReaderMutexLock& operator=(const ReaderMutexLock&) = delete; ReaderMutexLock& operator=(ReaderMutexLock&&) = delete; - ~ReaderMutexLock() ABSL_UNLOCK_FUNCTION() { this->mu_->ReaderUnlock(); } + ~ReaderMutexLock() ABSL_UNLOCK_FUNCTION() { this->mu_.unlock_shared(); } private: - Mutex* absl_nonnull const mu_; + Mutex& mu_; }; // WriterMutexLock @@ -661,27 +679,36 @@ // releases a write (exclusive) lock on a `Mutex` via RAII. class ABSL_SCOPED_LOCKABLE WriterMutexLock { public: - explicit WriterMutexLock(Mutex* absl_nonnull mu) + explicit WriterMutexLock(Mutex& mu ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this)) ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) : mu_(mu) { - mu->WriterLock(); + mu.WriterLock(); + } + + explicit WriterMutexLock(Mutex* absl_nonnull mu) + ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) + : WriterMutexLock(*mu) {} + + explicit WriterMutexLock(Mutex& mu ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this), + const Condition& cond) + ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) + : mu_(mu) { + mu.WriterLockWhen(cond); } explicit WriterMutexLock(Mutex* absl_nonnull mu, const Condition& cond) ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) - : mu_(mu) { - mu->WriterLockWhen(cond); - } + : WriterMutexLock(*mu, cond) {} WriterMutexLock(const WriterMutexLock&) = delete; WriterMutexLock(WriterMutexLock&&) = delete; WriterMutexLock& operator=(const WriterMutexLock&) = delete; WriterMutexLock& operator=(WriterMutexLock&&) = delete; - ~WriterMutexLock() ABSL_UNLOCK_FUNCTION() { this->mu_->WriterUnlock(); } + ~WriterMutexLock() ABSL_UNLOCK_FUNCTION() { this->mu_.WriterUnlock(); } private: - Mutex* absl_nonnull const mu_; + Mutex& mu_; }; // ----------------------------------------------------------------------------- @@ -728,7 +755,7 @@ // Example using a scope guard: // // { -// MutexLock lock(&mu_, count_is_zero); +// MutexLock lock(mu_, count_is_zero); // // ... // } // @@ -1034,7 +1061,7 @@ ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) : mu_(mu) { if (this->mu_ != nullptr) { - this->mu_->Lock(); + this->mu_->lock(); } } @@ -1048,7 +1075,7 @@ ~MutexLockMaybe() ABSL_UNLOCK_FUNCTION() { if (this->mu_ != nullptr) { - this->mu_->Unlock(); + this->mu_->unlock(); } } @@ -1066,21 +1093,30 @@ // mutex before destruction. `Release()` may be called at most once. class ABSL_SCOPED_LOCKABLE ReleasableMutexLock { public: + explicit ReleasableMutexLock(Mutex& mu ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY( + this)) ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) + : mu_(&mu) { + this->mu_->Lock(); + } + explicit ReleasableMutexLock(Mutex* absl_nonnull mu) ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) - : mu_(mu) { - this->mu_->Lock(); + : ReleasableMutexLock(*mu) {} + + explicit ReleasableMutexLock( + Mutex& mu ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this), + const Condition& cond) ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) + : mu_(&mu) { + this->mu_->LockWhen(cond); } explicit ReleasableMutexLock(Mutex* absl_nonnull mu, const Condition& cond) ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) - : mu_(mu) { - this->mu_->LockWhen(cond); - } + : ReleasableMutexLock(*mu, cond) {} ~ReleasableMutexLock() ABSL_UNLOCK_FUNCTION() { if (this->mu_ != nullptr) { - this->mu_->Unlock(); + this->mu_->unlock(); } }
diff --git a/absl/synchronization/mutex_benchmark.cc b/absl/synchronization/mutex_benchmark.cc index 1f33c0d..3557565 100644 --- a/absl/synchronization/mutex_benchmark.cc +++ b/absl/synchronization/mutex_benchmark.cc
@@ -46,8 +46,8 @@ void BM_TryLock(benchmark::State& state) { absl::Mutex mu; for (auto _ : state) { - if (mu.TryLock()) { - mu.Unlock(); + if (mu.try_lock()) { + mu.unlock(); } } } @@ -56,8 +56,8 @@ void BM_ReaderTryLock(benchmark::State& state) { static absl::NoDestructor<absl::Mutex> mu; for (auto _ : state) { - if (mu->ReaderTryLock()) { - mu->ReaderUnlock(); + if (mu->try_lock_shared()) { + mu->unlock_shared(); } } } @@ -145,7 +145,7 @@ shared->looping_threads.fetch_add(1); for (int i = 0; i < kBatchSize; i++) { { - absl::MutexLock l(&shared->mu); + absl::MutexLock l(shared->mu); shared->thread_has_mutex.store(true, std::memory_order_relaxed); // Spin until all other threads are either out of the benchmark loop // or blocked on the mutex. This ensures that the mutex queue is kept @@ -273,7 +273,7 @@ init->DecrementCount(); m->LockWhen(absl::Condition( static_cast<bool (*)(int*)>([](int* v) { return *v == 0; }), p)); - m->Unlock(); + m->unlock(); } }; @@ -299,15 +299,15 @@ init.Wait(); for (auto _ : state) { - mu.Lock(); - mu.Unlock(); // Each unlock requires Condition evaluation for our waiters. + mu.lock(); + mu.unlock(); // Each unlock requires Condition evaluation for our waiters. } - mu.Lock(); + mu.lock(); for (int i = 0; i < num_classes; i++) { equivalence_classes[i] = 0; } - mu.Unlock(); + mu.unlock(); } // Some configurations have higher thread limits than others.
diff --git a/absl/synchronization/mutex_test.cc b/absl/synchronization/mutex_test.cc index a71322a..82a2c06 100644 --- a/absl/synchronization/mutex_test.cc +++ b/absl/synchronization/mutex_test.cc
@@ -108,7 +108,7 @@ static void TestMu(TestContext *cxt, int c) { for (int i = 0; i != cxt->iterations; i++) { - absl::MutexLock l(&cxt->mu); + absl::MutexLock l(cxt->mu); int a = cxt->g0 + 1; cxt->g0 = a; cxt->g1--; @@ -119,17 +119,17 @@ for (int i = 0; i != cxt->iterations; i++) { do { std::this_thread::yield(); - } while (!cxt->mu.TryLock()); + } while (!cxt->mu.try_lock()); int a = cxt->g0 + 1; cxt->g0 = a; cxt->g1--; - cxt->mu.Unlock(); + cxt->mu.unlock(); } } static void TestR20ms(TestContext *cxt, int c) { for (int i = 0; i != cxt->iterations; i++) { - absl::ReaderMutexLock l(&cxt->mu); + absl::ReaderMutexLock l(cxt->mu); absl::SleepFor(absl::Milliseconds(20)); cxt->mu.AssertReaderHeld(); } @@ -138,7 +138,7 @@ static void TestRW(TestContext *cxt, int c) { if ((c & 1) == 0) { for (int i = 0; i != cxt->iterations; i++) { - absl::WriterMutexLock l(&cxt->mu); + absl::WriterMutexLock l(cxt->mu); cxt->g0++; cxt->g1--; cxt->mu.AssertHeld(); @@ -146,7 +146,7 @@ } } else { for (int i = 0; i != cxt->iterations; i++) { - absl::ReaderMutexLock l(&cxt->mu); + absl::ReaderMutexLock l(cxt->mu); CHECK_EQ(cxt->g0, -cxt->g1) << "Error in TestRW"; cxt->mu.AssertReaderHeld(); } @@ -168,7 +168,7 @@ MyContext mc; mc.target = c; mc.cxt = cxt; - absl::MutexLock l(&cxt->mu); + absl::MutexLock l(cxt->mu); cxt->mu.AssertHeld(); while (cxt->g0 < cxt->iterations) { cxt->mu.Await(absl::Condition(&mc, &MyContext::MyTurn)); @@ -184,7 +184,7 @@ static void TestSignalAll(TestContext *cxt, int c) { int target = c; - absl::MutexLock l(&cxt->mu); + absl::MutexLock l(cxt->mu); cxt->mu.AssertHeld(); while (cxt->g0 < cxt->iterations) { while (cxt->g0 != target && cxt->g0 != cxt->iterations) { @@ -202,7 +202,7 @@ static void TestSignal(TestContext *cxt, int c) { CHECK_EQ(cxt->threads, 2) << "TestSignal should use 2 threads"; int target = c; - absl::MutexLock l(&cxt->mu); + absl::MutexLock l(cxt->mu); cxt->mu.AssertHeld(); while (cxt->g0 < cxt->iterations) { while (cxt->g0 != target && cxt->g0 != cxt->iterations) { @@ -219,7 +219,7 @@ static void TestCVTimeout(TestContext *cxt, int c) { int target = c; - absl::MutexLock l(&cxt->mu); + absl::MutexLock l(cxt->mu); cxt->mu.AssertHeld(); while (cxt->g0 < cxt->iterations) { while (cxt->g0 != target && cxt->g0 != cxt->iterations) { @@ -243,7 +243,7 @@ absl::Condition false_cond(&kFalse); absl::Condition g0ge2(G0GE2, cxt); if (c == 0) { - absl::MutexLock l(&cxt->mu); + absl::MutexLock l(cxt->mu); absl::Time start = absl::Now(); if (use_cv) { @@ -311,7 +311,7 @@ CHECK_EQ(cxt->g0, cxt->threads) << "TestTime failed"; } else if (c == 1) { - absl::MutexLock l(&cxt->mu); + absl::MutexLock l(cxt->mu); const absl::Time start = absl::Now(); if (use_cv) { cxt->cv.WaitWithTimeout(&cxt->mu, absl::Milliseconds(500)); @@ -324,7 +324,7 @@ << "TestTime failed"; cxt->g0++; } else if (c == 2) { - absl::MutexLock l(&cxt->mu); + absl::MutexLock l(cxt->mu); if (use_cv) { while (cxt->g0 < 2) { cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(100)); @@ -335,7 +335,7 @@ } cxt->g0++; } else { - absl::MutexLock l(&cxt->mu); + absl::MutexLock l(cxt->mu); if (use_cv) { while (cxt->g0 < 2) { cxt->cv.Wait(&cxt->mu); @@ -353,9 +353,9 @@ static void EndTest(int *c0, int *c1, absl::Mutex *mu, absl::CondVar *cv, const std::function<void(int)> &cb) { - mu->Lock(); + mu->lock(); int c = (*c0)++; - mu->Unlock(); + mu->unlock(); cb(c); absl::MutexLock l(mu); (*c1)++; @@ -379,11 +379,11 @@ &EndTest, &c0, &c1, &mu2, &cv2, std::function<void(int)>(std::bind(test, cxt, std::placeholders::_1)))); } - mu2.Lock(); + mu2.lock(); while (c1 != threads) { cv2.Wait(&mu2); } - mu2.Unlock(); + mu2.unlock(); return cxt->g0; } @@ -424,7 +424,7 @@ static void WaitForA(TimeoutBugStruct *x) { x->mu.LockWhen(absl::Condition(&x->a)); x->a_waiter_count--; - x->mu.Unlock(); + x->mu.unlock(); } static bool NoAWaiters(TimeoutBugStruct *x) { return x->a_waiter_count == 0; } @@ -447,27 +447,27 @@ // Thread A. Sets barrier, waits for release using Mutex::Await, then // signals released_cv. pool->Schedule([&state] { - state.release_mu.Lock(); + state.release_mu.lock(); - state.barrier_mu.Lock(); + state.barrier_mu.lock(); state.barrier = true; - state.barrier_mu.Unlock(); + state.barrier_mu.unlock(); state.release_mu.Await(absl::Condition(&state.release)); state.released_cv.Signal(); - state.release_mu.Unlock(); + state.release_mu.unlock(); }); state.barrier_mu.LockWhen(absl::Condition(&state.barrier)); - state.barrier_mu.Unlock(); - state.release_mu.Lock(); + state.barrier_mu.unlock(); + state.release_mu.lock(); // Thread A is now blocked on release by way of Mutex::Await(). // Set release. Calling released_cv.Wait() should un-block thread A, // which will signal released_cv. If not, the test will hang. state.release = true; state.released_cv.Wait(&state.release_mu); - state.release_mu.Unlock(); + state.release_mu.unlock(); } // Test that a CondVar.WaitWithTimeout(&mutex) can un-block a call to @@ -488,20 +488,20 @@ // Thread A. Sets barrier, waits for release using Mutex::Await, then // signals released_cv. pool->Schedule([&state] { - state.release_mu.Lock(); + state.release_mu.lock(); - state.barrier_mu.Lock(); + state.barrier_mu.lock(); state.barrier = true; - state.barrier_mu.Unlock(); + state.barrier_mu.unlock(); state.release_mu.Await(absl::Condition(&state.release)); state.released_cv.Signal(); - state.release_mu.Unlock(); + state.release_mu.unlock(); }); state.barrier_mu.LockWhen(absl::Condition(&state.barrier)); - state.barrier_mu.Unlock(); - state.release_mu.Lock(); + state.barrier_mu.unlock(); + state.release_mu.lock(); // Thread A is now blocked on release by way of Mutex::Await(). // Set release. Calling released_cv.Wait() should un-block thread A, @@ -512,7 +512,7 @@ << "; Unrecoverable test failure: CondVar::WaitWithTimeout did not " "unblock the absl::Mutex::Await call in another thread."; - state.release_mu.Unlock(); + state.release_mu.unlock(); } // Test for regression of a bug in loop of TryRemove() @@ -538,7 +538,7 @@ x.a = true; // wakeup the two waiters on A x.mu.Await(absl::Condition(&NoAWaiters, &x)); // wait for them to exit - x.mu.Unlock(); + x.mu.unlock(); } struct CondVarWaitDeadlock : testing::TestWithParam<int> { @@ -558,27 +558,27 @@ void Waiter1() { if (read_lock1) { - mu.ReaderLock(); + mu.lock_shared(); while (!cond1) { cv.Wait(&mu); } - mu.ReaderUnlock(); + mu.unlock_shared(); } else { - mu.Lock(); + mu.lock(); while (!cond1) { cv.Wait(&mu); } - mu.Unlock(); + mu.unlock(); } } void Waiter2() { if (read_lock2) { mu.ReaderLockWhen(absl::Condition(&cond2)); - mu.ReaderUnlock(); + mu.unlock_shared(); } else { mu.LockWhen(absl::Condition(&cond2)); - mu.Unlock(); + mu.unlock(); } } }; @@ -602,21 +602,21 @@ absl::SleepFor(absl::Milliseconds(100)); // Wake condwaiter. - mu.Lock(); + mu.lock(); cond1 = true; if (signal_unlocked) { - mu.Unlock(); + mu.unlock(); cv.Signal(); } else { cv.Signal(); - mu.Unlock(); + mu.unlock(); } waiter1.reset(); // "join" waiter1 // Wake waiter. - mu.Lock(); + mu.lock(); cond2 = true; - mu.Unlock(); + mu.unlock(); waiter2.reset(); // "join" waiter2 } @@ -641,19 +641,19 @@ // Test for regression of a bug in loop of DequeueAllWakeable() static void AcquireAsReader(DequeueAllWakeableBugStruct *x) { - x->mu.ReaderLock(); - x->mu2.Lock(); + x->mu.lock_shared(); + x->mu2.lock(); x->unfinished_count--; x->done1 = (x->unfinished_count == 0); - x->mu2.Unlock(); + x->mu2.unlock(); // make sure that both readers acquired mu before we release it. absl::SleepFor(absl::Seconds(2)); - x->mu.ReaderUnlock(); + x->mu.unlock_shared(); - x->mu2.Lock(); + x->mu2.lock(); x->finished_count--; x->done2 = (x->finished_count == 0); - x->mu2.Unlock(); + x->mu2.unlock(); } // Test for regression of a bug in loop of DequeueAllWakeable() @@ -665,21 +665,21 @@ x.done1 = false; x.finished_count = 2; x.done2 = false; - x.mu.Lock(); // acquire mu exclusively + x.mu.lock(); // acquire mu exclusively // queue two thread that will block on reader locks on x.mu tp->Schedule(std::bind(&AcquireAsReader, &x)); tp->Schedule(std::bind(&AcquireAsReader, &x)); absl::SleepFor(absl::Seconds(1)); // give time for reader threads to block - x.mu.Unlock(); // wake them up + x.mu.unlock(); // wake them up // both readers should finish promptly EXPECT_TRUE( x.mu2.LockWhenWithTimeout(absl::Condition(&x.done1), absl::Seconds(10))); - x.mu2.Unlock(); + x.mu2.unlock(); EXPECT_TRUE( x.mu2.LockWhenWithTimeout(absl::Condition(&x.done2), absl::Seconds(10))); - x.mu2.Unlock(); + x.mu2.unlock(); } struct LockWhenTestStruct { @@ -691,15 +691,15 @@ }; static bool LockWhenTestIsCond(LockWhenTestStruct *s) { - s->mu2.Lock(); + s->mu2.lock(); s->waiting = true; - s->mu2.Unlock(); + s->mu2.unlock(); return s->cond; } static void LockWhenTestWaitForIsCond(LockWhenTestStruct *s) { s->mu1.LockWhen(absl::Condition(&LockWhenTestIsCond, s)); - s->mu1.Unlock(); + s->mu1.unlock(); } TEST(Mutex, LockWhen) { @@ -707,11 +707,11 @@ std::thread t(LockWhenTestWaitForIsCond, &s); s.mu2.LockWhen(absl::Condition(&s.waiting)); - s.mu2.Unlock(); + s.mu2.unlock(); - s.mu1.Lock(); + s.mu1.lock(); s.cond = true; - s.mu1.Unlock(); + s.mu1.unlock(); t.join(); } @@ -726,20 +726,20 @@ bool (*cond_lt_10)(int *) = [](int *p) { return *p < 10; }; std::thread t1([&mu, &n, &done, cond_eq_10]() { - absl::ReaderMutexLock lock(&mu, absl::Condition(cond_eq_10, &n)); + absl::ReaderMutexLock lock(mu, absl::Condition(cond_eq_10, &n)); done = true; }); std::thread t2[10]; for (std::thread &t : t2) { t = std::thread([&mu, &n, cond_lt_10]() { - absl::WriterMutexLock lock(&mu, absl::Condition(cond_lt_10, &n)); + absl::WriterMutexLock lock(mu, absl::Condition(cond_lt_10, &n)); ++n; }); } { - absl::MutexLock lock(&mu); + absl::MutexLock lock(mu); n = 0; } @@ -751,7 +751,7 @@ } // -------------------------------------------------------- -// The following test requires Mutex::ReaderLock to be a real shared +// The following test requires Mutex::lock_shared to be a real shared // lock, which is not the case in all builds. #if !defined(ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE) @@ -778,9 +778,9 @@ // L >= mu, L < mu_waiting_on_cond static bool IsCond(void *v) { ReaderDecrementBugStruct *x = reinterpret_cast<ReaderDecrementBugStruct *>(v); - x->mu2.Lock(); + x->mu2.lock(); x->waiting_on_cond = true; - x->mu2.Unlock(); + x->mu2.unlock(); return x->cond; } @@ -793,23 +793,23 @@ // L={} static void WaitForCond(ReaderDecrementBugStruct *x) { absl::Mutex dummy; - absl::MutexLock l(&dummy); + absl::MutexLock l(dummy); x->mu.LockWhen(absl::Condition(&IsCond, x)); x->done--; - x->mu.Unlock(); + x->mu.unlock(); } // L={} static void GetReadLock(ReaderDecrementBugStruct *x) { - x->mu.ReaderLock(); - x->mu2.Lock(); + x->mu.lock_shared(); + x->mu2.lock(); x->have_reader_lock = true; x->mu2.Await(absl::Condition(&x->complete)); - x->mu2.Unlock(); - x->mu.ReaderUnlock(); - x->mu.Lock(); + x->mu2.unlock(); + x->mu.unlock_shared(); + x->mu.lock(); x->done--; - x->mu.Unlock(); + x->mu.unlock(); } // Test for reader counter being decremented incorrectly by waiter @@ -825,32 +825,32 @@ // Run WaitForCond() and wait for it to sleep std::thread thread1(WaitForCond, &x); x.mu2.LockWhen(absl::Condition(&x.waiting_on_cond)); - x.mu2.Unlock(); + x.mu2.unlock(); // Run GetReadLock(), and wait for it to get the read lock std::thread thread2(GetReadLock, &x); x.mu2.LockWhen(absl::Condition(&x.have_reader_lock)); - x.mu2.Unlock(); + x.mu2.unlock(); // Get the reader lock ourselves, and release it. - x.mu.ReaderLock(); - x.mu.ReaderUnlock(); + x.mu.lock_shared(); + x.mu.unlock_shared(); // The lock should be held in read mode by GetReadLock(). // If we have the bug, the lock will be free. x.mu.AssertReaderHeld(); // Wake up all the threads. - x.mu2.Lock(); + x.mu2.lock(); x.complete = true; - x.mu2.Unlock(); + x.mu2.unlock(); // TODO(delesley): turn on analysis once lock upgrading is supported. // (This call upgrades the lock from shared to exclusive.) - x.mu.Lock(); + x.mu.lock(); x.cond = true; x.mu.Await(absl::Condition(&AllDone, &x)); - x.mu.Unlock(); + x.mu.unlock(); thread1.join(); thread2.join(); @@ -873,7 +873,7 @@ if ((j % 2) == 0) { mu[j].WriterLock(); } else { - mu[j].ReaderLock(); + mu[j].lock_shared(); } } } @@ -1069,15 +1069,15 @@ int *running) { absl::InsecureBitGen gen; std::uniform_int_distribution<int> random_millis(0, 15); - mu->ReaderLock(); + mu->lock_shared(); while (*running == 3) { absl::SleepFor(absl::Milliseconds(random_millis(gen))); cv->WaitWithTimeout(mu, absl::Milliseconds(random_millis(gen))); } - mu->ReaderUnlock(); - mu->Lock(); + mu->unlock_shared(); + mu->lock(); (*running)--; - mu->Unlock(); + mu->unlock(); } static bool IntIsZero(int *x) { return *x == 0; } @@ -1092,10 +1092,10 @@ tp->Schedule(std::bind(&ReaderForReaderOnCondVar, &mu, &cv, &running)); tp->Schedule(std::bind(&ReaderForReaderOnCondVar, &mu, &cv, &running)); absl::SleepFor(absl::Seconds(2)); - mu.Lock(); + mu.lock(); running--; mu.Await(absl::Condition(&IntIsZero, &running)); - mu.Unlock(); + mu.unlock(); } // -------------------------------------------------------- @@ -1119,7 +1119,7 @@ bool always_false = false; x->mu1.LockWhenWithTimeout(absl::Condition(&always_false), absl::Milliseconds(100)); - x->mu1.Unlock(); + x->mu1.unlock(); } CHECK_LT(x->value, 4) << "should not be invoked a fourth time"; @@ -1131,7 +1131,7 @@ // wait for cond0 to become true x->mu0.LockWhen(absl::Condition(&ConditionWithAcquire, x)); x->done = true; - x->mu0.Unlock(); + x->mu0.unlock(); } // Test for Condition whose function acquires other Mutexes @@ -1147,12 +1147,12 @@ // return false. absl::SleepFor(absl::Milliseconds(500)); // allow T time to hang - x.mu0.Lock(); + x.mu0.lock(); x.cv.WaitWithTimeout(&x.mu0, absl::Milliseconds(500)); // wake T // T will be woken because the Wait() will call ConditionWithAcquire() // for the second time, and it will return true. - x.mu0.Unlock(); + x.mu0.unlock(); // T will then acquire the lock and recheck its own condition. // It will find the condition true, as this is the third invocation, @@ -1168,7 +1168,7 @@ // is conceptually waiting both on the condition variable, and on mu2. x.mu0.LockWhen(absl::Condition(&x.done)); - x.mu0.Unlock(); + x.mu0.unlock(); } TEST(Mutex, DeadlockDetector) { @@ -1180,20 +1180,20 @@ absl::Mutex m3; absl::Mutex m4; - m1.Lock(); // m1 gets ID1 - m2.Lock(); // m2 gets ID2 - m3.Lock(); // m3 gets ID3 - m3.Unlock(); - m2.Unlock(); + m1.lock(); // m1 gets ID1 + m2.lock(); // m2 gets ID2 + m3.lock(); // m3 gets ID3 + m3.unlock(); + m2.unlock(); // m1 still held m1.ForgetDeadlockInfo(); // m1 loses ID - m2.Lock(); // m2 gets ID2 - m3.Lock(); // m3 gets ID3 - m4.Lock(); // m4 gets ID4 - m3.Unlock(); - m2.Unlock(); - m4.Unlock(); - m1.Unlock(); + m2.lock(); // m2 gets ID2 + m3.lock(); // m3 gets ID3 + m4.lock(); // m4 gets ID4 + m3.unlock(); + m2.unlock(); + m4.unlock(); + m1.unlock(); } // Bazel has a test "warning" file that programs can write to if the @@ -1248,18 +1248,18 @@ absl::Mutex mu0; absl::Mutex mu1; - bool got_mu0 = mu0.TryLock(); - mu1.Lock(); // acquire mu1 while holding mu0 + bool got_mu0 = mu0.try_lock(); + mu1.lock(); // acquire mu1 while holding mu0 if (got_mu0) { - mu0.Unlock(); + mu0.unlock(); } - if (mu0.TryLock()) { // try lock shouldn't cause deadlock detector to fire - mu0.Unlock(); + if (mu0.try_lock()) { // try lock shouldn't cause deadlock detector to fire + mu0.unlock(); } - mu0.Lock(); // acquire mu0 while holding mu1; should get one deadlock + mu0.lock(); // acquire mu0 while holding mu1; should get one deadlock // report here - mu0.Unlock(); - mu1.Unlock(); + mu0.unlock(); + mu1.unlock(); absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort); } @@ -1274,10 +1274,10 @@ // Check that we survive a deadlock with a lock cycle. std::vector<absl::Mutex> mutex(100); for (size_t i = 0; i != mutex.size(); i++) { - mutex[i].Lock(); - mutex[(i + 1) % mutex.size()].Lock(); - mutex[i].Unlock(); - mutex[(i + 1) % mutex.size()].Unlock(); + mutex[i].lock(); + mutex[(i + 1) % mutex.size()].lock(); + mutex[i].unlock(); + mutex[(i + 1) % mutex.size()].unlock(); } absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort); @@ -1297,10 +1297,10 @@ int end = std::min(n_locks, i + 5); // acquire and then release locks i, i+1, ..., i+4 for (int j = i; j < end; j++) { - array_of_locks[j].Lock(); + array_of_locks[j].lock(); } for (int j = i; j < end; j++) { - array_of_locks[j].Unlock(); + array_of_locks[j].unlock(); } } } @@ -1321,11 +1321,11 @@ absl::Mutex b, c; // Hold mutex. - a->Lock(); + a->lock(); // Force deadlock id assignment by acquiring another lock. - b.Lock(); - b.Unlock(); + b.lock(); + b.unlock(); // Delete the mutex. The Mutex destructor tries to remove held locks, // but the attempt isn't foolproof. It can fail if: @@ -1340,8 +1340,8 @@ // We should end up getting assigned the same deadlock id that was // freed up when "a" was deleted, which will cause a spurious deadlock // report if the held lock entry for "a" was not invalidated. - c.Lock(); - c.Unlock(); + c.lock(); + c.unlock(); } // -------------------------------------------------------- @@ -1576,11 +1576,11 @@ std::unique_ptr<absl::synchronization_internal::ThreadPool> pool = CreateDefaultPool(); RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] { - absl::MutexLock l(&mu); + absl::MutexLock l(mu); value = true; }); - absl::MutexLock lock(&mu); + absl::MutexLock lock(mu); absl::Time start_time = absl::Now(); absl::Condition cond(&value); bool result = @@ -1610,7 +1610,7 @@ std::unique_ptr<absl::synchronization_internal::ThreadPool> pool = CreateDefaultPool(); RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] { - absl::MutexLock l(&mu); + absl::MutexLock l(mu); value = true; }); @@ -1620,7 +1620,7 @@ params.use_absolute_deadline ? mu.LockWhenWithDeadline(cond, start_time + params.wait_timeout) : mu.LockWhenWithTimeout(cond, params.wait_timeout); - mu.Unlock(); + mu.unlock(); if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) { EXPECT_EQ(params.expected_result, result); @@ -1645,7 +1645,7 @@ std::unique_ptr<absl::synchronization_internal::ThreadPool> pool = CreateDefaultPool(); RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] { - absl::MutexLock l(&mu); + absl::MutexLock l(mu); value = true; }); @@ -1656,7 +1656,7 @@ start_time + params.wait_timeout) : mu.ReaderLockWhenWithTimeout(absl::Condition(&value), params.wait_timeout); - mu.ReaderUnlock(); + mu.unlock_shared(); if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) { EXPECT_EQ(params.expected_result, result); @@ -1682,12 +1682,12 @@ std::unique_ptr<absl::synchronization_internal::ThreadPool> pool = CreateDefaultPool(); RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] { - absl::MutexLock l(&mu); + absl::MutexLock l(mu); value = true; cv.Signal(); }); - absl::MutexLock lock(&mu); + absl::MutexLock lock(mu); absl::Time start_time = absl::Now(); absl::Duration timeout = params.wait_timeout; absl::Time deadline = start_time + timeout; @@ -1713,13 +1713,13 @@ logged_mutex.EnableDebugLog("fido_mutex"); absl::CondVar logged_cv; logged_cv.EnableDebugLog("rover_cv"); - logged_mutex.Lock(); + logged_mutex.lock(); logged_cv.WaitWithTimeout(&logged_mutex, absl::Milliseconds(20)); - logged_mutex.Unlock(); - logged_mutex.ReaderLock(); - logged_mutex.ReaderUnlock(); - logged_mutex.Lock(); - logged_mutex.Unlock(); + logged_mutex.unlock(); + logged_mutex.lock_shared(); + logged_mutex.unlock_shared(); + logged_mutex.lock(); + logged_mutex.unlock(); logged_cv.Signal(); logged_cv.SignalAll(); } @@ -1737,8 +1737,8 @@ alive[i] = true; mu->EnableDebugLog("Mutex"); mu->EnableInvariantDebugging(invariant, &alive[i]); - mu->Lock(); - mu->Unlock(); + mu->lock(); + mu->unlock(); mu->~Mutex(); alive[i] = false; } @@ -1764,8 +1764,8 @@ { absl::Mutex mu; mu.EnableInvariantDebugging([](void *) {}, nullptr); - mu.Lock(); - mu.Unlock(); + mu.lock(); + mu.unlock(); } { absl::Mutex mu; @@ -1902,7 +1902,7 @@ } TEST(Mutex, SignalExitedThread) { - // The test may expose a race when Mutex::Unlock signals a thread + // The test may expose a race when Mutex::unlock signals a thread // that has already exited. #if defined(__wasm__) || defined(__asmjs__) constexpr int kThreads = 1; // OOMs under WASM @@ -1915,11 +1915,11 @@ for (int i = 0; i < kThreads; i++) { absl::Mutex mu; std::thread t([&]() { - mu.Lock(); - mu.Unlock(); + mu.lock(); + mu.unlock(); }); - mu.Lock(); - mu.Unlock(); + mu.lock(); + mu.unlock(); t.join(); } }); @@ -1933,7 +1933,7 @@ std::atomic<bool> saw_wrote{false}; auto readfunc = [&]() { for (size_t i = 0; i < 10; ++i) { - absl::ReaderMutexLock lock(&mu); + absl::ReaderMutexLock lock(mu); if (wrote) { saw_wrote = true; break; @@ -1948,7 +1948,7 @@ // PerThreadSynch::priority, so the writer intentionally runs on a new thread. std::thread t3([&]() { // The writer should be able squeeze between the two alternating readers. - absl::MutexLock lock(&mu); + absl::MutexLock lock(mu); wrote = true; }); t1.join(); @@ -1980,30 +1980,30 @@ bool morph = false; std::thread th([&]() { EXPECT_EQ(0, pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m)); - mu.Lock(); + mu.lock(); locked = true; mu.Await(absl::Condition(¬ified)); - mu.Unlock(); + mu.unlock(); EXPECT_EQ(absl::synchronization_internal::GetOrCreateCurrentThreadIdentity() ->per_thread_synch.priority, param.sched_priority); - mu.Lock(); + mu.lock(); mu.Await(absl::Condition(&waiting)); morph = true; absl::SleepFor(absl::Seconds(1)); cv.Signal(); - mu.Unlock(); + mu.unlock(); }); - mu.Lock(); + mu.lock(); mu.Await(absl::Condition(&locked)); notified = true; - mu.Unlock(); - mu.Lock(); + mu.unlock(); + mu.lock(); waiting = true; while (!morph) { cv.Wait(&mu); } - mu.Unlock(); + mu.unlock(); th.join(); EXPECT_NE(absl::synchronization_internal::GetOrCreateCurrentThreadIdentity() ->per_thread_synch.priority, @@ -2018,20 +2018,20 @@ const bool kAlwaysTrue = true, kAlwaysFalse = false; const absl::Condition kTrueCond(&kAlwaysTrue), kFalseCond(&kAlwaysFalse); EXPECT_TRUE(mu.LockWhenWithTimeout(kTrueCond, absl::Milliseconds(1))); - mu.Unlock(); + mu.unlock(); EXPECT_FALSE(mu.LockWhenWithTimeout(kFalseCond, absl::Milliseconds(1))); EXPECT_TRUE(mu.AwaitWithTimeout(kTrueCond, absl::Milliseconds(1))); EXPECT_FALSE(mu.AwaitWithTimeout(kFalseCond, absl::Milliseconds(1))); std::thread th1([&]() { EXPECT_TRUE(mu.LockWhenWithTimeout(kTrueCond, absl::Milliseconds(1))); - mu.Unlock(); + mu.unlock(); }); std::thread th2([&]() { EXPECT_FALSE(mu.LockWhenWithTimeout(kFalseCond, absl::Milliseconds(1))); - mu.Unlock(); + mu.unlock(); }); absl::SleepFor(absl::Milliseconds(100)); - mu.Unlock(); + mu.unlock(); th1.join(); th2.join(); }
diff --git a/absl/synchronization/notification.cc b/absl/synchronization/notification.cc index a5853ab..a890c1b 100644 --- a/absl/synchronization/notification.cc +++ b/absl/synchronization/notification.cc
@@ -26,7 +26,7 @@ void Notification::Notify() { base_internal::TraceSignal(this, TraceObjectKind()); - MutexLock l(&this->mutex_); + MutexLock l(this->mutex_); #ifndef NDEBUG if (ABSL_PREDICT_FALSE(notified_yet_.load(std::memory_order_relaxed))) { @@ -43,7 +43,7 @@ Notification::~Notification() { // Make sure that the thread running Notify() exits before the object is // destructed. - MutexLock l(&this->mutex_); + MutexLock l(this->mutex_); } void Notification::WaitForNotification() const { @@ -51,7 +51,7 @@ if (!HasBeenNotifiedInternal(&this->notified_yet_)) { this->mutex_.LockWhen( Condition(&HasBeenNotifiedInternal, &this->notified_yet_)); - this->mutex_.Unlock(); + this->mutex_.unlock(); } base_internal::TraceContinue(this, TraceObjectKind()); } @@ -63,7 +63,7 @@ if (!notified) { notified = this->mutex_.LockWhenWithTimeout( Condition(&HasBeenNotifiedInternal, &this->notified_yet_), timeout); - this->mutex_.Unlock(); + this->mutex_.unlock(); } base_internal::TraceContinue(notified ? this : nullptr, TraceObjectKind()); return notified; @@ -75,7 +75,7 @@ if (!notified) { notified = this->mutex_.LockWhenWithDeadline( Condition(&HasBeenNotifiedInternal, &this->notified_yet_), deadline); - this->mutex_.Unlock(); + this->mutex_.unlock(); } base_internal::TraceContinue(notified ? this : nullptr, TraceObjectKind()); return notified;
diff --git a/absl/synchronization/notification_test.cc b/absl/synchronization/notification_test.cc index eedad17..ac5dccd 100644 --- a/absl/synchronization/notification_test.cc +++ b/absl/synchronization/notification_test.cc
@@ -34,17 +34,17 @@ ThreadSafeCounter() : count_(0) {} void Increment() { - MutexLock lock(&mutex_); + MutexLock lock(mutex_); ++count_; } int Get() const { - MutexLock lock(&mutex_); + MutexLock lock(mutex_); return count_; } void WaitUntilGreaterOrEqual(int n) { - MutexLock lock(&mutex_); + MutexLock lock(mutex_); auto cond = [this, n]() { return count_ >= n; }; mutex_.Await(Condition(&cond)); }
diff --git a/absl/time/BUILD.bazel b/absl/time/BUILD.bazel index b61999b..b68dd85 100644 --- a/absl/time/BUILD.bazel +++ b/absl/time/BUILD.bazel
@@ -121,6 +121,7 @@ "no_test_android_arm", "no_test_android_arm64", "no_test_android_x86", + "no_test_ios_sim_arm64", "no_test_ios_x86_64", "no_test_lexan", "no_test_loonix",
diff --git a/absl/time/clock.cc b/absl/time/clock.cc index f920ada..bdcd85b 100644 --- a/absl/time/clock.cc +++ b/absl/time/clock.cc
@@ -415,7 +415,7 @@ ABSL_LOCKS_EXCLUDED(time_state.lock) { // Serialize access to slow-path. Fast-path readers are not blocked yet, and // code below must not modify last_sample until the seqlock is acquired. - base_internal::SpinLockHolder l(&time_state.lock); + base_internal::SpinLockHolder l(time_state.lock); // Sample the kernel time base. This is the definition of // "now" if we take the slow path.
diff --git a/absl/time/internal/cctz/BUILD.bazel b/absl/time/internal/cctz/BUILD.bazel index 8abc804..6e17874 100644 --- a/absl/time/internal/cctz/BUILD.bazel +++ b/absl/time/internal/cctz/BUILD.bazel
@@ -83,9 +83,15 @@ ### tests -test_suite( - name = "all_tests", - visibility = ["//visibility:public"], +cc_library( + name = "test_time_zone_names", + testonly = True, + srcs = ["src/test_time_zone_names.cc"], + hdrs = ["src/test_time_zone_names.h"], + copts = ABSL_DEFAULT_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, + visibility = ["//visibility:private"], + deps = ["//absl/base:config"], ) cc_test( @@ -140,6 +146,7 @@ ], deps = [ ":civil_time", + ":test_time_zone_names", ":time_zone", "//absl/base:config", "@googletest//:gtest", @@ -164,6 +171,7 @@ tags = ["benchmark"], deps = [ ":civil_time", + ":test_time_zone_names", ":time_zone", "//absl/base:config", "@google_benchmark//:benchmark_main",
diff --git a/absl/time/internal/cctz/src/cctz_benchmark.cc b/absl/time/internal/cctz/src/cctz_benchmark.cc index ba7e149..ce27818 100644 --- a/absl/time/internal/cctz/src/cctz_benchmark.cc +++ b/absl/time/internal/cctz/src/cctz_benchmark.cc
@@ -23,6 +23,7 @@ #include "benchmark/benchmark.h" #include "absl/time/internal/cctz/include/cctz/civil_time.h" #include "absl/time/internal/cctz/include/cctz/time_zone.h" +#include "absl/time/internal/cctz/src/test_time_zone_names.h" #include "absl/time/internal/cctz/src/time_zone_impl.h" namespace { @@ -103,498 +104,10 @@ const char RFC1123_full[] = "%a, %d %b %Y %H:%M:%S %z"; const char RFC1123_no_wday[] = "%d %b %Y %H:%M:%S %z"; -// A list of known time-zone names. -// TODO: Refactor with src/time_zone_lookup_test.cc. -const char* const kTimeZoneNames[] = {"Africa/Abidjan", - "Africa/Accra", - "Africa/Addis_Ababa", - "Africa/Algiers", - "Africa/Asmara", - "Africa/Bamako", - "Africa/Bangui", - "Africa/Banjul", - "Africa/Bissau", - "Africa/Blantyre", - "Africa/Brazzaville", - "Africa/Bujumbura", - "Africa/Cairo", - "Africa/Casablanca", - "Africa/Ceuta", - "Africa/Conakry", - "Africa/Dakar", - "Africa/Dar_es_Salaam", - "Africa/Djibouti", - "Africa/Douala", - "Africa/El_Aaiun", - "Africa/Freetown", - "Africa/Gaborone", - "Africa/Harare", - "Africa/Johannesburg", - "Africa/Juba", - "Africa/Kampala", - "Africa/Khartoum", - "Africa/Kigali", - "Africa/Kinshasa", - "Africa/Lagos", - "Africa/Libreville", - "Africa/Lome", - "Africa/Luanda", - "Africa/Lubumbashi", - "Africa/Lusaka", - "Africa/Malabo", - "Africa/Maputo", - "Africa/Maseru", - "Africa/Mbabane", - "Africa/Mogadishu", - "Africa/Monrovia", - "Africa/Nairobi", - "Africa/Ndjamena", - "Africa/Niamey", - "Africa/Nouakchott", - "Africa/Ouagadougou", - "Africa/Porto-Novo", - "Africa/Sao_Tome", - "Africa/Timbuktu", - "Africa/Tripoli", - "Africa/Tunis", - "Africa/Windhoek", - "America/Adak", - "America/Anchorage", - "America/Anguilla", - "America/Antigua", - "America/Araguaina", - "America/Argentina/Buenos_Aires", - "America/Argentina/Catamarca", - "America/Argentina/Cordoba", - "America/Argentina/Jujuy", - "America/Argentina/La_Rioja", - "America/Argentina/Mendoza", - "America/Argentina/Rio_Gallegos", - "America/Argentina/Salta", - "America/Argentina/San_Juan", - "America/Argentina/San_Luis", - "America/Argentina/Tucuman", - "America/Argentina/Ushuaia", - "America/Aruba", - "America/Asuncion", - "America/Atikokan", - "America/Atka", - "America/Bahia", - "America/Bahia_Banderas", - "America/Barbados", - "America/Belem", - "America/Belize", - "America/Blanc-Sablon", - "America/Boa_Vista", - "America/Bogota", - "America/Boise", - "America/Cambridge_Bay", - "America/Campo_Grande", - "America/Cancun", - "America/Caracas", - "America/Cayenne", - "America/Cayman", - "America/Chicago", - "America/Chihuahua", - "America/Ciudad_Juarez", - "America/Coral_Harbour", - "America/Costa_Rica", - "America/Coyhaique", - "America/Creston", - "America/Cuiaba", - "America/Curacao", - "America/Danmarkshavn", - "America/Dawson", - "America/Dawson_Creek", - "America/Denver", - "America/Detroit", - "America/Dominica", - "America/Edmonton", - "America/Eirunepe", - "America/El_Salvador", - "America/Ensenada", - "America/Fort_Nelson", - "America/Fortaleza", - "America/Glace_Bay", - "America/Goose_Bay", - "America/Grand_Turk", - "America/Grenada", - "America/Guadeloupe", - "America/Guatemala", - "America/Guayaquil", - "America/Guyana", - "America/Halifax", - "America/Havana", - "America/Hermosillo", - "America/Indiana/Indianapolis", - "America/Indiana/Knox", - "America/Indiana/Marengo", - "America/Indiana/Petersburg", - "America/Indiana/Tell_City", - "America/Indiana/Vevay", - "America/Indiana/Vincennes", - "America/Indiana/Winamac", - "America/Inuvik", - "America/Iqaluit", - "America/Jamaica", - "America/Juneau", - "America/Kentucky/Louisville", - "America/Kentucky/Monticello", - "America/Kralendijk", - "America/La_Paz", - "America/Lima", - "America/Los_Angeles", - "America/Lower_Princes", - "America/Maceio", - "America/Managua", - "America/Manaus", - "America/Marigot", - "America/Martinique", - "America/Matamoros", - "America/Mazatlan", - "America/Menominee", - "America/Merida", - "America/Metlakatla", - "America/Mexico_City", - "America/Miquelon", - "America/Moncton", - "America/Monterrey", - "America/Montevideo", - "America/Montreal", - "America/Montserrat", - "America/Nassau", - "America/New_York", - "America/Nipigon", - "America/Nome", - "America/Noronha", - "America/North_Dakota/Beulah", - "America/North_Dakota/Center", - "America/North_Dakota/New_Salem", - "America/Nuuk", - "America/Ojinaga", - "America/Panama", - "America/Pangnirtung", - "America/Paramaribo", - "America/Phoenix", - "America/Port-au-Prince", - "America/Port_of_Spain", - "America/Porto_Acre", - "America/Porto_Velho", - "America/Puerto_Rico", - "America/Punta_Arenas", - "America/Rainy_River", - "America/Rankin_Inlet", - "America/Recife", - "America/Regina", - "America/Resolute", - "America/Rio_Branco", - "America/Santa_Isabel", - "America/Santarem", - "America/Santiago", - "America/Santo_Domingo", - "America/Sao_Paulo", - "America/Scoresbysund", - "America/Shiprock", - "America/Sitka", - "America/St_Barthelemy", - "America/St_Johns", - "America/St_Kitts", - "America/St_Lucia", - "America/St_Thomas", - "America/St_Vincent", - "America/Swift_Current", - "America/Tegucigalpa", - "America/Thule", - "America/Thunder_Bay", - "America/Tijuana", - "America/Toronto", - "America/Tortola", - "America/Vancouver", - "America/Virgin", - "America/Whitehorse", - "America/Winnipeg", - "America/Yakutat", - "America/Yellowknife", - "Antarctica/Casey", - "Antarctica/Davis", - "Antarctica/DumontDUrville", - "Antarctica/Macquarie", - "Antarctica/Mawson", - "Antarctica/McMurdo", - "Antarctica/Palmer", - "Antarctica/Rothera", - "Antarctica/Syowa", - "Antarctica/Troll", - "Antarctica/Vostok", - "Arctic/Longyearbyen", - "Asia/Aden", - "Asia/Almaty", - "Asia/Amman", - "Asia/Anadyr", - "Asia/Aqtau", - "Asia/Aqtobe", - "Asia/Ashgabat", - "Asia/Atyrau", - "Asia/Baghdad", - "Asia/Bahrain", - "Asia/Baku", - "Asia/Bangkok", - "Asia/Barnaul", - "Asia/Beirut", - "Asia/Bishkek", - "Asia/Brunei", - "Asia/Chita", - "Asia/Choibalsan", - "Asia/Chongqing", - "Asia/Colombo", - "Asia/Damascus", - "Asia/Dhaka", - "Asia/Dili", - "Asia/Dubai", - "Asia/Dushanbe", - "Asia/Famagusta", - "Asia/Gaza", - "Asia/Harbin", - "Asia/Hebron", - "Asia/Ho_Chi_Minh", - "Asia/Hong_Kong", - "Asia/Hovd", - "Asia/Irkutsk", - "Asia/Istanbul", - "Asia/Jakarta", - "Asia/Jayapura", - "Asia/Jerusalem", - "Asia/Kabul", - "Asia/Kamchatka", - "Asia/Karachi", - "Asia/Kashgar", - "Asia/Kathmandu", - "Asia/Khandyga", - "Asia/Kolkata", - "Asia/Krasnoyarsk", - "Asia/Kuala_Lumpur", - "Asia/Kuching", - "Asia/Kuwait", - "Asia/Macau", - "Asia/Magadan", - "Asia/Makassar", - "Asia/Manila", - "Asia/Muscat", - "Asia/Nicosia", - "Asia/Novokuznetsk", - "Asia/Novosibirsk", - "Asia/Omsk", - "Asia/Oral", - "Asia/Phnom_Penh", - "Asia/Pontianak", - "Asia/Pyongyang", - "Asia/Qatar", - "Asia/Qostanay", - "Asia/Qyzylorda", - "Asia/Riyadh", - "Asia/Sakhalin", - "Asia/Samarkand", - "Asia/Seoul", - "Asia/Shanghai", - "Asia/Singapore", - "Asia/Srednekolymsk", - "Asia/Taipei", - "Asia/Tashkent", - "Asia/Tbilisi", - "Asia/Tehran", - "Asia/Tel_Aviv", - "Asia/Thimphu", - "Asia/Tokyo", - "Asia/Tomsk", - "Asia/Ulaanbaatar", - "Asia/Urumqi", - "Asia/Ust-Nera", - "Asia/Vientiane", - "Asia/Vladivostok", - "Asia/Yakutsk", - "Asia/Yangon", - "Asia/Yekaterinburg", - "Asia/Yerevan", - "Atlantic/Azores", - "Atlantic/Bermuda", - "Atlantic/Canary", - "Atlantic/Cape_Verde", - "Atlantic/Faroe", - "Atlantic/Jan_Mayen", - "Atlantic/Madeira", - "Atlantic/Reykjavik", - "Atlantic/South_Georgia", - "Atlantic/St_Helena", - "Atlantic/Stanley", - "Australia/Adelaide", - "Australia/Brisbane", - "Australia/Broken_Hill", - "Australia/Canberra", - "Australia/Currie", - "Australia/Darwin", - "Australia/Eucla", - "Australia/Hobart", - "Australia/Lindeman", - "Australia/Lord_Howe", - "Australia/Melbourne", - "Australia/Perth", - "Australia/Sydney", - "Australia/Yancowinna", - "Etc/GMT", - "Etc/GMT+0", - "Etc/GMT+1", - "Etc/GMT+10", - "Etc/GMT+11", - "Etc/GMT+12", - "Etc/GMT+2", - "Etc/GMT+3", - "Etc/GMT+4", - "Etc/GMT+5", - "Etc/GMT+6", - "Etc/GMT+7", - "Etc/GMT+8", - "Etc/GMT+9", - "Etc/GMT-0", - "Etc/GMT-1", - "Etc/GMT-10", - "Etc/GMT-11", - "Etc/GMT-12", - "Etc/GMT-13", - "Etc/GMT-14", - "Etc/GMT-2", - "Etc/GMT-3", - "Etc/GMT-4", - "Etc/GMT-5", - "Etc/GMT-6", - "Etc/GMT-7", - "Etc/GMT-8", - "Etc/GMT-9", - "Etc/GMT0", - "Etc/Greenwich", - "Etc/UCT", - "Etc/UTC", - "Etc/Universal", - "Etc/Zulu", - "Europe/Amsterdam", - "Europe/Andorra", - "Europe/Astrakhan", - "Europe/Athens", - "Europe/Belfast", - "Europe/Belgrade", - "Europe/Berlin", - "Europe/Bratislava", - "Europe/Brussels", - "Europe/Bucharest", - "Europe/Budapest", - "Europe/Busingen", - "Europe/Chisinau", - "Europe/Copenhagen", - "Europe/Dublin", - "Europe/Gibraltar", - "Europe/Guernsey", - "Europe/Helsinki", - "Europe/Isle_of_Man", - "Europe/Istanbul", - "Europe/Jersey", - "Europe/Kaliningrad", - "Europe/Kirov", - "Europe/Kyiv", - "Europe/Lisbon", - "Europe/Ljubljana", - "Europe/London", - "Europe/Luxembourg", - "Europe/Madrid", - "Europe/Malta", - "Europe/Mariehamn", - "Europe/Minsk", - "Europe/Monaco", - "Europe/Moscow", - "Europe/Nicosia", - "Europe/Oslo", - "Europe/Paris", - "Europe/Podgorica", - "Europe/Prague", - "Europe/Riga", - "Europe/Rome", - "Europe/Samara", - "Europe/San_Marino", - "Europe/Sarajevo", - "Europe/Saratov", - "Europe/Simferopol", - "Europe/Skopje", - "Europe/Sofia", - "Europe/Stockholm", - "Europe/Tallinn", - "Europe/Tirane", - "Europe/Tiraspol", - "Europe/Ulyanovsk", - "Europe/Vaduz", - "Europe/Vatican", - "Europe/Vienna", - "Europe/Vilnius", - "Europe/Volgograd", - "Europe/Warsaw", - "Europe/Zagreb", - "Europe/Zurich", - "Factory", - "Indian/Antananarivo", - "Indian/Chagos", - "Indian/Christmas", - "Indian/Cocos", - "Indian/Comoro", - "Indian/Kerguelen", - "Indian/Mahe", - "Indian/Maldives", - "Indian/Mauritius", - "Indian/Mayotte", - "Indian/Reunion", - "Pacific/Apia", - "Pacific/Auckland", - "Pacific/Bougainville", - "Pacific/Chatham", - "Pacific/Chuuk", - "Pacific/Easter", - "Pacific/Efate", - "Pacific/Fakaofo", - "Pacific/Fiji", - "Pacific/Funafuti", - "Pacific/Galapagos", - "Pacific/Gambier", - "Pacific/Guadalcanal", - "Pacific/Guam", - "Pacific/Honolulu", - "Pacific/Johnston", - "Pacific/Kanton", - "Pacific/Kiritimati", - "Pacific/Kosrae", - "Pacific/Kwajalein", - "Pacific/Majuro", - "Pacific/Marquesas", - "Pacific/Midway", - "Pacific/Nauru", - "Pacific/Niue", - "Pacific/Norfolk", - "Pacific/Noumea", - "Pacific/Pago_Pago", - "Pacific/Palau", - "Pacific/Pitcairn", - "Pacific/Pohnpei", - "Pacific/Port_Moresby", - "Pacific/Rarotonga", - "Pacific/Saipan", - "Pacific/Samoa", - "Pacific/Tahiti", - "Pacific/Tarawa", - "Pacific/Tongatapu", - "Pacific/Wake", - "Pacific/Wallis", - "Pacific/Yap", - "UTC", - nullptr}; - std::vector<std::string> AllTimeZoneNames() { std::vector<std::string> names; - for (const char* const* namep = kTimeZoneNames; *namep != nullptr; ++namep) { + for (const char* const* namep = cctz::kTimeZoneNames; *namep != nullptr; + ++namep) { names.push_back(std::string("file:") + *namep); } assert(!names.empty()); @@ -889,6 +402,7 @@ RFC3339_sec, // 3 "%Y-%m-%d%ET%H:%M:%S", // 4 "%Y-%m-%d", // 5 + "%F%ET%T", // 6 }; const int kNumFormats = sizeof(kFormats) / sizeof(kFormats[0]);
diff --git a/absl/time/internal/cctz/src/test_time_zone_names.cc b/absl/time/internal/cctz/src/test_time_zone_names.cc new file mode 100644 index 0000000..ab54c9a --- /dev/null +++ b/absl/time/internal/cctz/src/test_time_zone_names.cc
@@ -0,0 +1,515 @@ +// Copyright 2025 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/time/internal/cctz/src/test_time_zone_names.h" + +#include "absl/base/config.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace time_internal { +namespace cctz { + +// A list of known time-zone names. +const char* const kTimeZoneNames[] = {"Africa/Abidjan", + "Africa/Accra", + "Africa/Addis_Ababa", + "Africa/Algiers", + "Africa/Asmara", + "Africa/Bamako", + "Africa/Bangui", + "Africa/Banjul", + "Africa/Bissau", + "Africa/Blantyre", + "Africa/Brazzaville", + "Africa/Bujumbura", + "Africa/Cairo", + "Africa/Casablanca", + "Africa/Ceuta", + "Africa/Conakry", + "Africa/Dakar", + "Africa/Dar_es_Salaam", + "Africa/Djibouti", + "Africa/Douala", + "Africa/El_Aaiun", + "Africa/Freetown", + "Africa/Gaborone", + "Africa/Harare", + "Africa/Johannesburg", + "Africa/Juba", + "Africa/Kampala", + "Africa/Khartoum", + "Africa/Kigali", + "Africa/Kinshasa", + "Africa/Lagos", + "Africa/Libreville", + "Africa/Lome", + "Africa/Luanda", + "Africa/Lubumbashi", + "Africa/Lusaka", + "Africa/Malabo", + "Africa/Maputo", + "Africa/Maseru", + "Africa/Mbabane", + "Africa/Mogadishu", + "Africa/Monrovia", + "Africa/Nairobi", + "Africa/Ndjamena", + "Africa/Niamey", + "Africa/Nouakchott", + "Africa/Ouagadougou", + "Africa/Porto-Novo", + "Africa/Sao_Tome", + "Africa/Timbuktu", + "Africa/Tripoli", + "Africa/Tunis", + "Africa/Windhoek", + "America/Adak", + "America/Anchorage", + "America/Anguilla", + "America/Antigua", + "America/Araguaina", + "America/Argentina/Buenos_Aires", + "America/Argentina/Catamarca", + "America/Argentina/Cordoba", + "America/Argentina/Jujuy", + "America/Argentina/La_Rioja", + "America/Argentina/Mendoza", + "America/Argentina/Rio_Gallegos", + "America/Argentina/Salta", + "America/Argentina/San_Juan", + "America/Argentina/San_Luis", + "America/Argentina/Tucuman", + "America/Argentina/Ushuaia", + "America/Aruba", + "America/Asuncion", + "America/Atikokan", + "America/Atka", + "America/Bahia", + "America/Bahia_Banderas", + "America/Barbados", + "America/Belem", + "America/Belize", + "America/Blanc-Sablon", + "America/Boa_Vista", + "America/Bogota", + "America/Boise", + "America/Cambridge_Bay", + "America/Campo_Grande", + "America/Cancun", + "America/Caracas", + "America/Cayenne", + "America/Cayman", + "America/Chicago", + "America/Chihuahua", + "America/Ciudad_Juarez", + "America/Coral_Harbour", + "America/Costa_Rica", + "America/Coyhaique", + "America/Creston", + "America/Cuiaba", + "America/Curacao", + "America/Danmarkshavn", + "America/Dawson", + "America/Dawson_Creek", + "America/Denver", + "America/Detroit", + "America/Dominica", + "America/Edmonton", + "America/Eirunepe", + "America/El_Salvador", + "America/Ensenada", + "America/Fort_Nelson", + "America/Fortaleza", + "America/Glace_Bay", + "America/Goose_Bay", + "America/Grand_Turk", + "America/Grenada", + "America/Guadeloupe", + "America/Guatemala", + "America/Guayaquil", + "America/Guyana", + "America/Halifax", + "America/Havana", + "America/Hermosillo", + "America/Indiana/Indianapolis", + "America/Indiana/Knox", + "America/Indiana/Marengo", + "America/Indiana/Petersburg", + "America/Indiana/Tell_City", + "America/Indiana/Vevay", + "America/Indiana/Vincennes", + "America/Indiana/Winamac", + "America/Inuvik", + "America/Iqaluit", + "America/Jamaica", + "America/Juneau", + "America/Kentucky/Louisville", + "America/Kentucky/Monticello", + "America/Kralendijk", + "America/La_Paz", + "America/Lima", + "America/Los_Angeles", + "America/Lower_Princes", + "America/Maceio", + "America/Managua", + "America/Manaus", + "America/Marigot", + "America/Martinique", + "America/Matamoros", + "America/Mazatlan", + "America/Menominee", + "America/Merida", + "America/Metlakatla", + "America/Mexico_City", + "America/Miquelon", + "America/Moncton", + "America/Monterrey", + "America/Montevideo", + "America/Montreal", + "America/Montserrat", + "America/Nassau", + "America/New_York", + "America/Nipigon", + "America/Nome", + "America/Noronha", + "America/North_Dakota/Beulah", + "America/North_Dakota/Center", + "America/North_Dakota/New_Salem", + "America/Nuuk", + "America/Ojinaga", + "America/Panama", + "America/Pangnirtung", + "America/Paramaribo", + "America/Phoenix", + "America/Port-au-Prince", + "America/Port_of_Spain", + "America/Porto_Acre", + "America/Porto_Velho", + "America/Puerto_Rico", + "America/Punta_Arenas", + "America/Rainy_River", + "America/Rankin_Inlet", + "America/Recife", + "America/Regina", + "America/Resolute", + "America/Rio_Branco", + "America/Santa_Isabel", + "America/Santarem", + "America/Santiago", + "America/Santo_Domingo", + "America/Sao_Paulo", + "America/Scoresbysund", + "America/Shiprock", + "America/Sitka", + "America/St_Barthelemy", + "America/St_Johns", + "America/St_Kitts", + "America/St_Lucia", + "America/St_Thomas", + "America/St_Vincent", + "America/Swift_Current", + "America/Tegucigalpa", + "America/Thule", + "America/Thunder_Bay", + "America/Tijuana", + "America/Toronto", + "America/Tortola", + "America/Vancouver", + "America/Virgin", + "America/Whitehorse", + "America/Winnipeg", + "America/Yakutat", + "America/Yellowknife", + "Antarctica/Casey", + "Antarctica/Davis", + "Antarctica/DumontDUrville", + "Antarctica/Macquarie", + "Antarctica/Mawson", + "Antarctica/McMurdo", + "Antarctica/Palmer", + "Antarctica/Rothera", + "Antarctica/Syowa", + "Antarctica/Troll", + "Antarctica/Vostok", + "Arctic/Longyearbyen", + "Asia/Aden", + "Asia/Almaty", + "Asia/Amman", + "Asia/Anadyr", + "Asia/Aqtau", + "Asia/Aqtobe", + "Asia/Ashgabat", + "Asia/Atyrau", + "Asia/Baghdad", + "Asia/Bahrain", + "Asia/Baku", + "Asia/Bangkok", + "Asia/Barnaul", + "Asia/Beirut", + "Asia/Bishkek", + "Asia/Brunei", + "Asia/Chita", + "Asia/Choibalsan", + "Asia/Chongqing", + "Asia/Colombo", + "Asia/Damascus", + "Asia/Dhaka", + "Asia/Dili", + "Asia/Dubai", + "Asia/Dushanbe", + "Asia/Famagusta", + "Asia/Gaza", + "Asia/Harbin", + "Asia/Hebron", + "Asia/Ho_Chi_Minh", + "Asia/Hong_Kong", + "Asia/Hovd", + "Asia/Irkutsk", + "Asia/Istanbul", + "Asia/Jakarta", + "Asia/Jayapura", + "Asia/Jerusalem", + "Asia/Kabul", + "Asia/Kamchatka", + "Asia/Karachi", + "Asia/Kashgar", + "Asia/Kathmandu", + "Asia/Khandyga", + "Asia/Kolkata", + "Asia/Krasnoyarsk", + "Asia/Kuala_Lumpur", + "Asia/Kuching", + "Asia/Kuwait", + "Asia/Macau", + "Asia/Magadan", + "Asia/Makassar", + "Asia/Manila", + "Asia/Muscat", + "Asia/Nicosia", + "Asia/Novokuznetsk", + "Asia/Novosibirsk", + "Asia/Omsk", + "Asia/Oral", + "Asia/Phnom_Penh", + "Asia/Pontianak", + "Asia/Pyongyang", + "Asia/Qatar", + "Asia/Qostanay", + "Asia/Qyzylorda", + "Asia/Riyadh", + "Asia/Sakhalin", + "Asia/Samarkand", + "Asia/Seoul", + "Asia/Shanghai", + "Asia/Singapore", + "Asia/Srednekolymsk", + "Asia/Taipei", + "Asia/Tashkent", + "Asia/Tbilisi", + "Asia/Tehran", + "Asia/Tel_Aviv", + "Asia/Thimphu", + "Asia/Tokyo", + "Asia/Tomsk", + "Asia/Ulaanbaatar", + "Asia/Urumqi", + "Asia/Ust-Nera", + "Asia/Vientiane", + "Asia/Vladivostok", + "Asia/Yakutsk", + "Asia/Yangon", + "Asia/Yekaterinburg", + "Asia/Yerevan", + "Atlantic/Azores", + "Atlantic/Bermuda", + "Atlantic/Canary", + "Atlantic/Cape_Verde", + "Atlantic/Faroe", + "Atlantic/Jan_Mayen", + "Atlantic/Madeira", + "Atlantic/Reykjavik", + "Atlantic/South_Georgia", + "Atlantic/St_Helena", + "Atlantic/Stanley", + "Australia/Adelaide", + "Australia/Brisbane", + "Australia/Broken_Hill", + "Australia/Canberra", + "Australia/Currie", + "Australia/Darwin", + "Australia/Eucla", + "Australia/Hobart", + "Australia/Lindeman", + "Australia/Lord_Howe", + "Australia/Melbourne", + "Australia/Perth", + "Australia/Sydney", + "Australia/Yancowinna", + "Etc/GMT", + "Etc/GMT+0", + "Etc/GMT+1", + "Etc/GMT+10", + "Etc/GMT+11", + "Etc/GMT+12", + "Etc/GMT+2", + "Etc/GMT+3", + "Etc/GMT+4", + "Etc/GMT+5", + "Etc/GMT+6", + "Etc/GMT+7", + "Etc/GMT+8", + "Etc/GMT+9", + "Etc/GMT-0", + "Etc/GMT-1", + "Etc/GMT-10", + "Etc/GMT-11", + "Etc/GMT-12", + "Etc/GMT-13", + "Etc/GMT-14", + "Etc/GMT-2", + "Etc/GMT-3", + "Etc/GMT-4", + "Etc/GMT-5", + "Etc/GMT-6", + "Etc/GMT-7", + "Etc/GMT-8", + "Etc/GMT-9", + "Etc/GMT0", + "Etc/Greenwich", + "Etc/UCT", + "Etc/UTC", + "Etc/Universal", + "Etc/Zulu", + "Europe/Amsterdam", + "Europe/Andorra", + "Europe/Astrakhan", + "Europe/Athens", + "Europe/Belfast", + "Europe/Belgrade", + "Europe/Berlin", + "Europe/Bratislava", + "Europe/Brussels", + "Europe/Bucharest", + "Europe/Budapest", + "Europe/Busingen", + "Europe/Chisinau", + "Europe/Copenhagen", + "Europe/Dublin", + "Europe/Gibraltar", + "Europe/Guernsey", + "Europe/Helsinki", + "Europe/Isle_of_Man", + "Europe/Istanbul", + "Europe/Jersey", + "Europe/Kaliningrad", + "Europe/Kirov", + "Europe/Kyiv", + "Europe/Lisbon", + "Europe/Ljubljana", + "Europe/London", + "Europe/Luxembourg", + "Europe/Madrid", + "Europe/Malta", + "Europe/Mariehamn", + "Europe/Minsk", + "Europe/Monaco", + "Europe/Moscow", + "Europe/Nicosia", + "Europe/Oslo", + "Europe/Paris", + "Europe/Podgorica", + "Europe/Prague", + "Europe/Riga", + "Europe/Rome", + "Europe/Samara", + "Europe/San_Marino", + "Europe/Sarajevo", + "Europe/Saratov", + "Europe/Simferopol", + "Europe/Skopje", + "Europe/Sofia", + "Europe/Stockholm", + "Europe/Tallinn", + "Europe/Tirane", + "Europe/Tiraspol", + "Europe/Ulyanovsk", + "Europe/Vaduz", + "Europe/Vatican", + "Europe/Vienna", + "Europe/Vilnius", + "Europe/Volgograd", + "Europe/Warsaw", + "Europe/Zagreb", + "Europe/Zurich", + "Factory", + "Indian/Antananarivo", + "Indian/Chagos", + "Indian/Christmas", + "Indian/Cocos", + "Indian/Comoro", + "Indian/Kerguelen", + "Indian/Mahe", + "Indian/Maldives", + "Indian/Mauritius", + "Indian/Mayotte", + "Indian/Reunion", + "Pacific/Apia", + "Pacific/Auckland", + "Pacific/Bougainville", + "Pacific/Chatham", + "Pacific/Chuuk", + "Pacific/Easter", + "Pacific/Efate", + "Pacific/Fakaofo", + "Pacific/Fiji", + "Pacific/Funafuti", + "Pacific/Galapagos", + "Pacific/Gambier", + "Pacific/Guadalcanal", + "Pacific/Guam", + "Pacific/Honolulu", + "Pacific/Johnston", + "Pacific/Kanton", + "Pacific/Kiritimati", + "Pacific/Kosrae", + "Pacific/Kwajalein", + "Pacific/Majuro", + "Pacific/Marquesas", + "Pacific/Midway", + "Pacific/Nauru", + "Pacific/Niue", + "Pacific/Norfolk", + "Pacific/Noumea", + "Pacific/Pago_Pago", + "Pacific/Palau", + "Pacific/Pitcairn", + "Pacific/Pohnpei", + "Pacific/Port_Moresby", + "Pacific/Rarotonga", + "Pacific/Saipan", + "Pacific/Samoa", + "Pacific/Tahiti", + "Pacific/Tarawa", + "Pacific/Tongatapu", + "Pacific/Wake", + "Pacific/Wallis", + "Pacific/Yap", + "UTC", + nullptr}; + +} // namespace cctz +} // namespace time_internal +ABSL_NAMESPACE_END +} // namespace absl
diff --git a/absl/time/internal/cctz/src/test_time_zone_names.h b/absl/time/internal/cctz/src/test_time_zone_names.h new file mode 100644 index 0000000..1993994 --- /dev/null +++ b/absl/time/internal/cctz/src/test_time_zone_names.h
@@ -0,0 +1,33 @@ +// Copyright 2025 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_TIME_INTERNAL_CCTZ_TEST_TIME_ZONE_NAMES_H_ +#define ABSL_TIME_INTERNAL_CCTZ_TEST_TIME_ZONE_NAMES_H_ + +#include "absl/base/config.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace time_internal { +namespace cctz { + +// A list of known time-zone names. +extern const char* const kTimeZoneNames[]; + +} // namespace cctz +} // namespace time_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_TIME_INTERNAL_CCTZ_TEST_TIME_ZONE_NAMES_H_
diff --git a/absl/time/internal/cctz/src/time_zone_format.cc b/absl/time/internal/cctz/src/time_zone_format.cc index 0e5f32f..f739e02 100644 --- a/absl/time/internal/cctz/src/time_zone_format.cc +++ b/absl/time/internal/cctz/src/time_zone_format.cc
@@ -117,7 +117,7 @@ tm.tm_mday = al.cs.day(); tm.tm_mon = al.cs.month() - 1; - // Saturate tm.tm_year is cases of over/underflow. + // Saturate tm.tm_year in cases of over/underflow. if (al.cs.year() < std::numeric_limits<int>::min() + 1900) { tm.tm_year = std::numeric_limits<int>::min(); } else if (al.cs.year() - 1900 > std::numeric_limits<int>::max()) { @@ -338,7 +338,7 @@ const std::tm tm = ToTM(al); // Scratch buffer for internal conversions. - char buf[3 + kDigits10_64]; // enough for longest conversion + char buf[6 + (kDigits10_64 + 2)]; // enough for longest conversion %F char* const ep = buf + sizeof(buf); char* bp; // works back from ep @@ -382,7 +382,7 @@ if (cur == end || (cur - percent) % 2 == 0) continue; // Simple specifiers that we handle ourselves. - if (strchr("YmdeUuWwHMSzZs%", *cur)) { + if (strchr("YmdeFUuWwHMSTzZs%", *cur)) { if (cur - 1 != pending) { FormatTM(&result, std::string(pending, cur - 1), tm); } @@ -403,6 +403,14 @@ if (*cur == 'e' && *bp == '0') *bp = ' '; // for Windows result.append(bp, static_cast<std::size_t>(ep - bp)); break; + case 'F': + bp = Format02d(ep, al.cs.day()); + *--bp = '-'; + bp = Format02d(bp, al.cs.month()); + *--bp = '-'; + bp = Format64(bp, 0, al.cs.year()); + result.append(bp, static_cast<std::size_t>(ep - bp)); + break; case 'U': bp = Format02d(ep, ToWeek(civil_day(al.cs), weekday::sunday)); result.append(bp, static_cast<std::size_t>(ep - bp)); @@ -431,6 +439,14 @@ bp = Format02d(ep, al.cs.second()); result.append(bp, static_cast<std::size_t>(ep - bp)); break; + case 'T': + bp = Format02d(ep, al.cs.second()); + *--bp = ':'; + bp = Format02d(bp, al.cs.minute()); + *--bp = ':'; + bp = Format02d(bp, al.cs.hour()); + result.append(bp, static_cast<std::size_t>(ep - bp)); + break; case 'z': bp = FormatOffset(ep, al.offset, ""); result.append(bp, static_cast<std::size_t>(ep - bp)); @@ -769,6 +785,20 @@ data = ParseInt(data, 2, 1, 31, &tm.tm_mday); week_num = -1; continue; + case 'F': + data = ParseInt(data, 0, kyearmin, kyearmax, &year); + if (data != nullptr) { + saw_year = true; + data = (*data == '-' ? data + 1 : nullptr); + } + data = ParseInt(data, 2, 1, 12, &tm.tm_mon); + if (data != nullptr) { + tm.tm_mon -= 1; + data = (*data == '-' ? data + 1 : nullptr); + } + data = ParseInt(data, 2, 1, 31, &tm.tm_mday); + week_num = -1; + continue; case 'U': data = ParseInt(data, 0, 0, 53, &week_num); week_start = weekday::sunday; @@ -794,13 +824,20 @@ case 'S': data = ParseInt(data, 2, 0, 60, &tm.tm_sec); continue; + case 'T': + data = ParseInt(data, 2, 0, 23, &tm.tm_hour); + twelve_hour = false; + data = (data != nullptr && *data == ':' ? data + 1 : nullptr); + data = ParseInt(data, 2, 0, 59, &tm.tm_min); + data = (data != nullptr && *data == ':' ? data + 1 : nullptr); + data = ParseInt(data, 2, 0, 60, &tm.tm_sec); + continue; case 'I': case 'l': case 'r': // probably uses %I twelve_hour = true; break; case 'R': // uses %H - case 'T': // uses %H case 'c': // probably uses %H case 'X': // probably uses %H twelve_hour = false;
diff --git a/absl/time/internal/cctz/src/time_zone_format_test.cc b/absl/time/internal/cctz/src/time_zone_format_test.cc index 4a6c71f..a270f4d 100644 --- a/absl/time/internal/cctz/src/time_zone_format_test.cc +++ b/absl/time/internal/cctz/src/time_zone_format_test.cc
@@ -169,23 +169,22 @@ TEST(Format, PosixConversions) { const time_zone tz = utc_time_zone(); - auto tp = chrono::system_clock::from_time_t(0); + auto tp = + chrono::system_clock::from_time_t(308189482); // 1979-10-08T00:11:22Z - TestFormatSpecifier(tp, tz, "%d", "01"); - TestFormatSpecifier(tp, tz, "%e", " 1"); // extension but internal support + TestFormatSpecifier(tp, tz, "%d", "08"); + TestFormatSpecifier(tp, tz, "%e", " 8"); // extension but internal support TestFormatSpecifier(tp, tz, "%H", "00"); TestFormatSpecifier(tp, tz, "%I", "12"); - TestFormatSpecifier(tp, tz, "%j", "001"); - TestFormatSpecifier(tp, tz, "%m", "01"); - TestFormatSpecifier(tp, tz, "%M", "00"); - TestFormatSpecifier(tp, tz, "%S", "00"); - TestFormatSpecifier(tp, tz, "%U", "00"); -#if !defined(__EMSCRIPTEN__) - TestFormatSpecifier(tp, tz, "%w", "4"); // 4=Thursday -#endif - TestFormatSpecifier(tp, tz, "%W", "00"); - TestFormatSpecifier(tp, tz, "%y", "70"); - TestFormatSpecifier(tp, tz, "%Y", "1970"); + TestFormatSpecifier(tp, tz, "%j", "281"); + TestFormatSpecifier(tp, tz, "%m", "10"); + TestFormatSpecifier(tp, tz, "%M", "11"); + TestFormatSpecifier(tp, tz, "%S", "22"); + TestFormatSpecifier(tp, tz, "%U", "40"); + TestFormatSpecifier(tp, tz, "%w", "1"); // 1=Monday + TestFormatSpecifier(tp, tz, "%W", "41"); + TestFormatSpecifier(tp, tz, "%y", "79"); + TestFormatSpecifier(tp, tz, "%Y", "1979"); TestFormatSpecifier(tp, tz, "%z", "+0000"); TestFormatSpecifier(tp, tz, "%Z", "UTC"); TestFormatSpecifier(tp, tz, "%%", "%"); @@ -193,21 +192,21 @@ #if defined(__linux__) // SU/C99/TZ extensions TestFormatSpecifier(tp, tz, "%C", "19"); - TestFormatSpecifier(tp, tz, "%D", "01/01/70"); - TestFormatSpecifier(tp, tz, "%F", "1970-01-01"); - TestFormatSpecifier(tp, tz, "%g", "70"); - TestFormatSpecifier(tp, tz, "%G", "1970"); + TestFormatSpecifier(tp, tz, "%D", "10/08/79"); + TestFormatSpecifier(tp, tz, "%F", "1979-10-08"); + TestFormatSpecifier(tp, tz, "%g", "79"); + TestFormatSpecifier(tp, tz, "%G", "1979"); #if defined(__GLIBC__) TestFormatSpecifier(tp, tz, "%k", " 0"); TestFormatSpecifier(tp, tz, "%l", "12"); #endif TestFormatSpecifier(tp, tz, "%n", "\n"); - TestFormatSpecifier(tp, tz, "%R", "00:00"); + TestFormatSpecifier(tp, tz, "%R", "00:11"); TestFormatSpecifier(tp, tz, "%t", "\t"); - TestFormatSpecifier(tp, tz, "%T", "00:00:00"); - TestFormatSpecifier(tp, tz, "%u", "4"); // 4=Thursday - TestFormatSpecifier(tp, tz, "%V", "01"); - TestFormatSpecifier(tp, tz, "%s", "0"); + TestFormatSpecifier(tp, tz, "%T", "00:11:22"); + TestFormatSpecifier(tp, tz, "%u", "1"); // 1=Monday + TestFormatSpecifier(tp, tz, "%V", "41"); + TestFormatSpecifier(tp, tz, "%s", "308189482"); #endif }
diff --git a/absl/time/internal/cctz/src/time_zone_lookup_test.cc b/absl/time/internal/cctz/src/time_zone_lookup_test.cc index e1bea28..cd08a35 100644 --- a/absl/time/internal/cctz/src/time_zone_lookup_test.cc +++ b/absl/time/internal/cctz/src/time_zone_lookup_test.cc
@@ -29,6 +29,7 @@ #include "gtest/gtest.h" #include "absl/time/internal/cctz/include/cctz/civil_time.h" +#include "absl/time/internal/cctz/src/test_time_zone_names.h" namespace chrono = std::chrono; @@ -39,494 +40,6 @@ namespace { -// A list of known time-zone names. -const char* const kTimeZoneNames[] = {"Africa/Abidjan", - "Africa/Accra", - "Africa/Addis_Ababa", - "Africa/Algiers", - "Africa/Asmara", - "Africa/Bamako", - "Africa/Bangui", - "Africa/Banjul", - "Africa/Bissau", - "Africa/Blantyre", - "Africa/Brazzaville", - "Africa/Bujumbura", - "Africa/Cairo", - "Africa/Casablanca", - "Africa/Ceuta", - "Africa/Conakry", - "Africa/Dakar", - "Africa/Dar_es_Salaam", - "Africa/Djibouti", - "Africa/Douala", - "Africa/El_Aaiun", - "Africa/Freetown", - "Africa/Gaborone", - "Africa/Harare", - "Africa/Johannesburg", - "Africa/Juba", - "Africa/Kampala", - "Africa/Khartoum", - "Africa/Kigali", - "Africa/Kinshasa", - "Africa/Lagos", - "Africa/Libreville", - "Africa/Lome", - "Africa/Luanda", - "Africa/Lubumbashi", - "Africa/Lusaka", - "Africa/Malabo", - "Africa/Maputo", - "Africa/Maseru", - "Africa/Mbabane", - "Africa/Mogadishu", - "Africa/Monrovia", - "Africa/Nairobi", - "Africa/Ndjamena", - "Africa/Niamey", - "Africa/Nouakchott", - "Africa/Ouagadougou", - "Africa/Porto-Novo", - "Africa/Sao_Tome", - "Africa/Timbuktu", - "Africa/Tripoli", - "Africa/Tunis", - "Africa/Windhoek", - "America/Adak", - "America/Anchorage", - "America/Anguilla", - "America/Antigua", - "America/Araguaina", - "America/Argentina/Buenos_Aires", - "America/Argentina/Catamarca", - "America/Argentina/Cordoba", - "America/Argentina/Jujuy", - "America/Argentina/La_Rioja", - "America/Argentina/Mendoza", - "America/Argentina/Rio_Gallegos", - "America/Argentina/Salta", - "America/Argentina/San_Juan", - "America/Argentina/San_Luis", - "America/Argentina/Tucuman", - "America/Argentina/Ushuaia", - "America/Aruba", - "America/Asuncion", - "America/Atikokan", - "America/Atka", - "America/Bahia", - "America/Bahia_Banderas", - "America/Barbados", - "America/Belem", - "America/Belize", - "America/Blanc-Sablon", - "America/Boa_Vista", - "America/Bogota", - "America/Boise", - "America/Cambridge_Bay", - "America/Campo_Grande", - "America/Cancun", - "America/Caracas", - "America/Cayenne", - "America/Cayman", - "America/Chicago", - "America/Chihuahua", - "America/Ciudad_Juarez", - "America/Coral_Harbour", - "America/Costa_Rica", - "America/Coyhaique", - "America/Creston", - "America/Cuiaba", - "America/Curacao", - "America/Danmarkshavn", - "America/Dawson", - "America/Dawson_Creek", - "America/Denver", - "America/Detroit", - "America/Dominica", - "America/Edmonton", - "America/Eirunepe", - "America/El_Salvador", - "America/Ensenada", - "America/Fort_Nelson", - "America/Fortaleza", - "America/Glace_Bay", - "America/Goose_Bay", - "America/Grand_Turk", - "America/Grenada", - "America/Guadeloupe", - "America/Guatemala", - "America/Guayaquil", - "America/Guyana", - "America/Halifax", - "America/Havana", - "America/Hermosillo", - "America/Indiana/Indianapolis", - "America/Indiana/Knox", - "America/Indiana/Marengo", - "America/Indiana/Petersburg", - "America/Indiana/Tell_City", - "America/Indiana/Vevay", - "America/Indiana/Vincennes", - "America/Indiana/Winamac", - "America/Inuvik", - "America/Iqaluit", - "America/Jamaica", - "America/Juneau", - "America/Kentucky/Louisville", - "America/Kentucky/Monticello", - "America/Kralendijk", - "America/La_Paz", - "America/Lima", - "America/Los_Angeles", - "America/Lower_Princes", - "America/Maceio", - "America/Managua", - "America/Manaus", - "America/Marigot", - "America/Martinique", - "America/Matamoros", - "America/Mazatlan", - "America/Menominee", - "America/Merida", - "America/Metlakatla", - "America/Mexico_City", - "America/Miquelon", - "America/Moncton", - "America/Monterrey", - "America/Montevideo", - "America/Montreal", - "America/Montserrat", - "America/Nassau", - "America/New_York", - "America/Nipigon", - "America/Nome", - "America/Noronha", - "America/North_Dakota/Beulah", - "America/North_Dakota/Center", - "America/North_Dakota/New_Salem", - "America/Nuuk", - "America/Ojinaga", - "America/Panama", - "America/Pangnirtung", - "America/Paramaribo", - "America/Phoenix", - "America/Port-au-Prince", - "America/Port_of_Spain", - "America/Porto_Acre", - "America/Porto_Velho", - "America/Puerto_Rico", - "America/Punta_Arenas", - "America/Rainy_River", - "America/Rankin_Inlet", - "America/Recife", - "America/Regina", - "America/Resolute", - "America/Rio_Branco", - "America/Santa_Isabel", - "America/Santarem", - "America/Santiago", - "America/Santo_Domingo", - "America/Sao_Paulo", - "America/Scoresbysund", - "America/Shiprock", - "America/Sitka", - "America/St_Barthelemy", - "America/St_Johns", - "America/St_Kitts", - "America/St_Lucia", - "America/St_Thomas", - "America/St_Vincent", - "America/Swift_Current", - "America/Tegucigalpa", - "America/Thule", - "America/Thunder_Bay", - "America/Tijuana", - "America/Toronto", - "America/Tortola", - "America/Vancouver", - "America/Virgin", - "America/Whitehorse", - "America/Winnipeg", - "America/Yakutat", - "America/Yellowknife", - "Antarctica/Casey", - "Antarctica/Davis", - "Antarctica/DumontDUrville", - "Antarctica/Macquarie", - "Antarctica/Mawson", - "Antarctica/McMurdo", - "Antarctica/Palmer", - "Antarctica/Rothera", - "Antarctica/Syowa", - "Antarctica/Troll", - "Antarctica/Vostok", - "Arctic/Longyearbyen", - "Asia/Aden", - "Asia/Almaty", - "Asia/Amman", - "Asia/Anadyr", - "Asia/Aqtau", - "Asia/Aqtobe", - "Asia/Ashgabat", - "Asia/Atyrau", - "Asia/Baghdad", - "Asia/Bahrain", - "Asia/Baku", - "Asia/Bangkok", - "Asia/Barnaul", - "Asia/Beirut", - "Asia/Bishkek", - "Asia/Brunei", - "Asia/Chita", - "Asia/Choibalsan", - "Asia/Chongqing", - "Asia/Colombo", - "Asia/Damascus", - "Asia/Dhaka", - "Asia/Dili", - "Asia/Dubai", - "Asia/Dushanbe", - "Asia/Famagusta", - "Asia/Gaza", - "Asia/Harbin", - "Asia/Hebron", - "Asia/Ho_Chi_Minh", - "Asia/Hong_Kong", - "Asia/Hovd", - "Asia/Irkutsk", - "Asia/Istanbul", - "Asia/Jakarta", - "Asia/Jayapura", - "Asia/Jerusalem", - "Asia/Kabul", - "Asia/Kamchatka", - "Asia/Karachi", - "Asia/Kashgar", - "Asia/Kathmandu", - "Asia/Khandyga", - "Asia/Kolkata", - "Asia/Krasnoyarsk", - "Asia/Kuala_Lumpur", - "Asia/Kuching", - "Asia/Kuwait", - "Asia/Macau", - "Asia/Magadan", - "Asia/Makassar", - "Asia/Manila", - "Asia/Muscat", - "Asia/Nicosia", - "Asia/Novokuznetsk", - "Asia/Novosibirsk", - "Asia/Omsk", - "Asia/Oral", - "Asia/Phnom_Penh", - "Asia/Pontianak", - "Asia/Pyongyang", - "Asia/Qatar", - "Asia/Qostanay", - "Asia/Qyzylorda", - "Asia/Riyadh", - "Asia/Sakhalin", - "Asia/Samarkand", - "Asia/Seoul", - "Asia/Shanghai", - "Asia/Singapore", - "Asia/Srednekolymsk", - "Asia/Taipei", - "Asia/Tashkent", - "Asia/Tbilisi", - "Asia/Tehran", - "Asia/Tel_Aviv", - "Asia/Thimphu", - "Asia/Tokyo", - "Asia/Tomsk", - "Asia/Ulaanbaatar", - "Asia/Urumqi", - "Asia/Ust-Nera", - "Asia/Vientiane", - "Asia/Vladivostok", - "Asia/Yakutsk", - "Asia/Yangon", - "Asia/Yekaterinburg", - "Asia/Yerevan", - "Atlantic/Azores", - "Atlantic/Bermuda", - "Atlantic/Canary", - "Atlantic/Cape_Verde", - "Atlantic/Faroe", - "Atlantic/Jan_Mayen", - "Atlantic/Madeira", - "Atlantic/Reykjavik", - "Atlantic/South_Georgia", - "Atlantic/St_Helena", - "Atlantic/Stanley", - "Australia/Adelaide", - "Australia/Brisbane", - "Australia/Broken_Hill", - "Australia/Canberra", - "Australia/Currie", - "Australia/Darwin", - "Australia/Eucla", - "Australia/Hobart", - "Australia/Lindeman", - "Australia/Lord_Howe", - "Australia/Melbourne", - "Australia/Perth", - "Australia/Sydney", - "Australia/Yancowinna", - "Etc/GMT", - "Etc/GMT+0", - "Etc/GMT+1", - "Etc/GMT+10", - "Etc/GMT+11", - "Etc/GMT+12", - "Etc/GMT+2", - "Etc/GMT+3", - "Etc/GMT+4", - "Etc/GMT+5", - "Etc/GMT+6", - "Etc/GMT+7", - "Etc/GMT+8", - "Etc/GMT+9", - "Etc/GMT-0", - "Etc/GMT-1", - "Etc/GMT-10", - "Etc/GMT-11", - "Etc/GMT-12", - "Etc/GMT-13", - "Etc/GMT-14", - "Etc/GMT-2", - "Etc/GMT-3", - "Etc/GMT-4", - "Etc/GMT-5", - "Etc/GMT-6", - "Etc/GMT-7", - "Etc/GMT-8", - "Etc/GMT-9", - "Etc/GMT0", - "Etc/Greenwich", - "Etc/UCT", - "Etc/UTC", - "Etc/Universal", - "Etc/Zulu", - "Europe/Amsterdam", - "Europe/Andorra", - "Europe/Astrakhan", - "Europe/Athens", - "Europe/Belfast", - "Europe/Belgrade", - "Europe/Berlin", - "Europe/Bratislava", - "Europe/Brussels", - "Europe/Bucharest", - "Europe/Budapest", - "Europe/Busingen", - "Europe/Chisinau", - "Europe/Copenhagen", - "Europe/Dublin", - "Europe/Gibraltar", - "Europe/Guernsey", - "Europe/Helsinki", - "Europe/Isle_of_Man", - "Europe/Istanbul", - "Europe/Jersey", - "Europe/Kaliningrad", - "Europe/Kirov", - "Europe/Kyiv", - "Europe/Lisbon", - "Europe/Ljubljana", - "Europe/London", - "Europe/Luxembourg", - "Europe/Madrid", - "Europe/Malta", - "Europe/Mariehamn", - "Europe/Minsk", - "Europe/Monaco", - "Europe/Moscow", - "Europe/Nicosia", - "Europe/Oslo", - "Europe/Paris", - "Europe/Podgorica", - "Europe/Prague", - "Europe/Riga", - "Europe/Rome", - "Europe/Samara", - "Europe/San_Marino", - "Europe/Sarajevo", - "Europe/Saratov", - "Europe/Simferopol", - "Europe/Skopje", - "Europe/Sofia", - "Europe/Stockholm", - "Europe/Tallinn", - "Europe/Tirane", - "Europe/Tiraspol", - "Europe/Ulyanovsk", - "Europe/Vaduz", - "Europe/Vatican", - "Europe/Vienna", - "Europe/Vilnius", - "Europe/Volgograd", - "Europe/Warsaw", - "Europe/Zagreb", - "Europe/Zurich", - "Factory", - "Indian/Antananarivo", - "Indian/Chagos", - "Indian/Christmas", - "Indian/Cocos", - "Indian/Comoro", - "Indian/Kerguelen", - "Indian/Mahe", - "Indian/Maldives", - "Indian/Mauritius", - "Indian/Mayotte", - "Indian/Reunion", - "Pacific/Apia", - "Pacific/Auckland", - "Pacific/Bougainville", - "Pacific/Chatham", - "Pacific/Chuuk", - "Pacific/Easter", - "Pacific/Efate", - "Pacific/Fakaofo", - "Pacific/Fiji", - "Pacific/Funafuti", - "Pacific/Galapagos", - "Pacific/Gambier", - "Pacific/Guadalcanal", - "Pacific/Guam", - "Pacific/Honolulu", - "Pacific/Johnston", - "Pacific/Kanton", - "Pacific/Kiritimati", - "Pacific/Kosrae", - "Pacific/Kwajalein", - "Pacific/Majuro", - "Pacific/Marquesas", - "Pacific/Midway", - "Pacific/Nauru", - "Pacific/Niue", - "Pacific/Norfolk", - "Pacific/Noumea", - "Pacific/Pago_Pago", - "Pacific/Palau", - "Pacific/Pitcairn", - "Pacific/Pohnpei", - "Pacific/Port_Moresby", - "Pacific/Rarotonga", - "Pacific/Saipan", - "Pacific/Samoa", - "Pacific/Tahiti", - "Pacific/Tarawa", - "Pacific/Tongatapu", - "Pacific/Wake", - "Pacific/Wallis", - "Pacific/Yap", - "UTC", - nullptr}; - // Helper to return a loaded time zone by value (UTC on error). time_zone LoadZone(const std::string& name) { time_zone tz;
diff --git a/absl/types/span.h b/absl/types/span.h index 3338e87..016376e 100644 --- a/absl/types/span.h +++ b/absl/types/span.h
@@ -726,24 +726,38 @@ // } // template <int&... ExplicitArgumentBarrier, typename T> -constexpr Span<T> MakeSpan(T* absl_nullable ptr, size_t size) noexcept { +constexpr Span<T> MakeSpan(T* absl_nullable ptr ABSL_ATTRIBUTE_LIFETIME_BOUND, + size_t size) noexcept { return Span<T>(ptr, size); } template <int&... ExplicitArgumentBarrier, typename T> -Span<T> MakeSpan(T* absl_nullable begin, T* absl_nullable end) noexcept { +Span<T> MakeSpan(T* absl_nullable begin ABSL_ATTRIBUTE_LIFETIME_BOUND, + T* absl_nullable end) noexcept { ABSL_HARDENING_ASSERT(begin <= end); return Span<T>(begin, static_cast<size_t>(end - begin)); } template <int&... ExplicitArgumentBarrier, typename C> constexpr auto MakeSpan(C& c) noexcept // NOLINT(runtime/references) - -> decltype(absl::MakeSpan(span_internal::GetData(c), c.size())) { + -> std::enable_if_t<span_internal::IsView<C>::value, + decltype(absl::MakeSpan(span_internal::GetData(c), + c.size()))> { + return MakeSpan(span_internal::GetData(c), c.size()); +} + +template <int&... ExplicitArgumentBarrier, typename C> +constexpr auto MakeSpan( + C& c ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept // NOLINT(runtime/references) + -> std::enable_if_t<!span_internal::IsView<C>::value, + decltype(absl::MakeSpan(span_internal::GetData(c), + c.size()))> { return MakeSpan(span_internal::GetData(c), c.size()); } template <int&... ExplicitArgumentBarrier, typename T, size_t N> -constexpr Span<T> MakeSpan(T (&array)[N]) noexcept { +constexpr Span<T> MakeSpan( + T (&array ABSL_ATTRIBUTE_LIFETIME_BOUND)[N]) noexcept { return Span<T>(array, N); } @@ -772,25 +786,36 @@ // ProcessInts(absl::MakeConstSpan(std::vector<int>{ 0, 0, 0 })); // template <int&... ExplicitArgumentBarrier, typename T> -constexpr Span<const T> MakeConstSpan(T* absl_nullable ptr, - size_t size) noexcept { +constexpr Span<const T> MakeConstSpan( + T* absl_nullable ptr ABSL_ATTRIBUTE_LIFETIME_BOUND, size_t size) noexcept { return Span<const T>(ptr, size); } template <int&... ExplicitArgumentBarrier, typename T> -Span<const T> MakeConstSpan(T* absl_nullable begin, +Span<const T> MakeConstSpan(T* absl_nullable begin + ABSL_ATTRIBUTE_LIFETIME_BOUND, T* absl_nullable end) noexcept { ABSL_HARDENING_ASSERT(begin <= end); return Span<const T>(begin, end - begin); } template <int&... ExplicitArgumentBarrier, typename C> -constexpr auto MakeConstSpan(const C& c) noexcept -> decltype(MakeSpan(c)) { +constexpr auto MakeConstSpan(const C& c) noexcept + -> std::enable_if_t<span_internal::IsView<C>::value, + decltype(MakeSpan(c))> { + return MakeSpan(c); +} + +template <int&... ExplicitArgumentBarrier, typename C> +constexpr auto MakeConstSpan(const C& c ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept + -> std::enable_if_t<!span_internal::IsView<C>::value, + decltype(MakeSpan(c))> { return MakeSpan(c); } template <int&... ExplicitArgumentBarrier, typename T, size_t N> -constexpr Span<const T> MakeConstSpan(const T (&array)[N]) noexcept { +constexpr Span<const T> MakeConstSpan( + const T (&array ABSL_ATTRIBUTE_LIFETIME_BOUND)[N]) noexcept { return Span<const T>(array, N); } ABSL_NAMESPACE_END