Export of internal Abseil changes

--
69b3ab092ee0fef3d27f589e709280c341f006c6 by Greg Falcon <gfalcon@google.com>:

Import of CCTZ from GitHub.

PiperOrigin-RevId: 321005878

--
3a4038cd0cea6455453a7ae82f2de7e91d7e2bc1 by Abseil Team <absl-team@google.com>:

Google-internal changes only.

PiperOrigin-RevId: 320994821

--
f9d9a93782924df6ffc351a271c239ca4bdff3c8 by Derek Mauro <dmauro@google.com>:

Update Linux latest toolchains, most notably to GCC 10.1

This create a new "hybrid" docker image that includes the latest
versions of both GCC and LLVM. Since the LLVM build targets Debian 10,
but Debian 10 uses an older version of libstdc++ that doesn't have
full C++20 support, the easiest solution is to use the GCC/Debian 10
base image from DockerHub and copy LLVM into it.

This also includes fixes to get the build working with the
new toolchains.

PiperOrigin-RevId: 320991795

--
43129cd66dc4439b36d85030800a3929f20d9f86 by Abseil Team <absl-team@google.com>:

Rollback import of CCTZ from GitHub (breaks MSAN tests)

  - e87b391f0d10ae9c3d2e70e4a3633337d2c5e643 handle "slim" TZif files in TimeZoneInfo::ExtendTransitio... by Bradley White <14679271+devbww@users.noreply.github.com>

PiperOrigin-RevId: 320978767

--
2a343a55f297d433c1521920f0bd20ddd2dc71e8 by Derek Mauro <dmauro@google.com>:

Use ABSL_HAVE_ATTRIBUTE in thread_annotations.h

PiperOrigin-RevId: 320956378

--
f6f3e8333c9ef6e6441586be6587bbfb1c8c8127 by Gennadiy Rozental <rogeeff@google.com>:

Import of CCTZ from GitHub.

PiperOrigin-RevId: 320952592

--
3cc2bcce3533ac1233c0536232b07eea45fe8ed0 by Derek Mauro <dmauro@google.com>:

Internal change

PiperOrigin-RevId: 320862698

--
4e22066476744609e42c475b55e3cbd874f04c39 by Gennadiy Rozental <rogeeff@google.com>:

Internal change

PiperOrigin-RevId: 320461277
GitOrigin-RevId: 69b3ab092ee0fef3d27f589e709280c341f006c6
Change-Id: I36f547711e7078d52f2e0a1ff3f4c903056a2b9e
diff --git a/WORKSPACE b/WORKSPACE
index 1a1da6c..9633819 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -20,9 +20,9 @@
 # GoogleTest/GoogleMock framework. Used by most unit-tests.
 http_archive(
     name = "com_google_googletest",
-    urls = ["https://github.com/google/googletest/archive/011959aafddcd30611003de96cfd8d7a7685c700.zip"],  # 2020-05-14T00:36:05Z
-    strip_prefix = "googletest-011959aafddcd30611003de96cfd8d7a7685c700",
-    sha256 = "6a5d7d63cd6e0ad2a7130471105a3b83799a7a2b14ef7ec8d742b54f01a4833c",
+    urls = ["https://github.com/google/googletest/archive/8567b09290fe402cf01923e2131c5635b8ed851b.zip"],  # 2020-06-12T22:24:28Z
+    strip_prefix = "googletest-8567b09290fe402cf01923e2131c5635b8ed851b",
+    sha256 = "9a8a166eb6a56c7b3d7b19dc2c946fe4778fd6f21c7a12368ad3b836d8f1be48",
 )
 
 # Google benchmark.
diff --git a/absl/BUILD.bazel b/absl/BUILD.bazel
index e45d15a..1019ab5 100644
--- a/absl/BUILD.bazel
+++ b/absl/BUILD.bazel
@@ -61,5 +61,8 @@
 
 config_setting(
     name = "wasm",
-    values = {"cpu": "wasm32"},
+    values = {
+        "cpu": "wasm32",
+    },
+    visibility = [":__subpackages__"],
 )
diff --git a/absl/base/internal/low_level_scheduling.h b/absl/base/internal/low_level_scheduling.h
index ed0b4bf..6ef79fb 100644
--- a/absl/base/internal/low_level_scheduling.h
+++ b/absl/base/internal/low_level_scheduling.h
@@ -18,6 +18,7 @@
 #ifndef ABSL_BASE_INTERNAL_LOW_LEVEL_SCHEDULING_H_
 #define ABSL_BASE_INTERNAL_LOW_LEVEL_SCHEDULING_H_
 
+#include "absl/base/internal/raw_logging.h"
 #include "absl/base/internal/scheduling_mode.h"
 #include "absl/base/macros.h"
 
@@ -29,6 +30,13 @@
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
+class CondVar;
+class Mutex;
+
+namespace synchronization_internal {
+int MutexDelay(int32_t c, int mode);
+}  // namespace synchronization_internal
+
 namespace base_internal {
 
 class SchedulingHelper;  // To allow use of SchedulingGuard.
@@ -76,9 +84,23 @@
     bool disabled;
   };
 
+  // A scoped helper to enable rescheduling temporarily.
+  // REQUIRES: destructor must run in same thread as constructor.
+  class ScopedEnable {
+   public:
+    ScopedEnable();
+    ~ScopedEnable();
+
+   private:
+    int scheduling_disabled_depth_;
+  };
+
   // Access to SchedulingGuard is explicitly permitted.
+  friend class absl::CondVar;
+  friend class absl::Mutex;
   friend class SchedulingHelper;
   friend class SpinLock;
+  friend int absl::synchronization_internal::MutexDelay(int32_t c, int mode);
 
   SchedulingGuard(const SchedulingGuard&) = delete;
   SchedulingGuard& operator=(const SchedulingGuard&) = delete;
@@ -100,6 +122,12 @@
   return;
 }
 
+inline SchedulingGuard::ScopedEnable::ScopedEnable()
+    : scheduling_disabled_depth_(0) {}
+inline SchedulingGuard::ScopedEnable::~ScopedEnable() {
+  ABSL_RAW_CHECK(scheduling_disabled_depth_ == 0, "disable unused warning");
+}
+
 }  // namespace base_internal
 ABSL_NAMESPACE_END
 }  // namespace absl
diff --git a/absl/base/thread_annotations.h b/absl/base/thread_annotations.h
index 6a7112d..e23fff1 100644
--- a/absl/base/thread_annotations.h
+++ b/absl/base/thread_annotations.h
@@ -39,12 +39,6 @@
 // TODO(mbonadei): Remove after the backward compatibility period.
 #include "absl/base/internal/thread_annotations.h"  // IWYU pragma: export
 
-#if defined(__clang__)
-#define ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(x) __attribute__((x))
-#else
-#define ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(x)  // no-op
-#endif
-
 // ABSL_GUARDED_BY()
 //
 // Documents if a shared field or global variable needs to be protected by a
@@ -62,8 +56,11 @@
 //     int p1_ ABSL_GUARDED_BY(mu_);
 //     ...
 //   };
-#define ABSL_GUARDED_BY(x) \
-  ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(guarded_by(x))
+#if ABSL_HAVE_ATTRIBUTE(guarded_by)
+#define ABSL_GUARDED_BY(x) __attribute__((guarded_by(x)))
+#else
+#define ABSL_GUARDED_BY(x)
+#endif
 
 // ABSL_PT_GUARDED_BY()
 //
@@ -85,8 +82,11 @@
 //   // `q_`, guarded by `mu1_`, points to a shared memory location that is
 //   // guarded by `mu2_`:
 //   int *q_ ABSL_GUARDED_BY(mu1_) ABSL_PT_GUARDED_BY(mu2_);
-#define ABSL_PT_GUARDED_BY(x) \
-  ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(pt_guarded_by(x))
+#if ABSL_HAVE_ATTRIBUTE(pt_guarded_by)
+#define ABSL_PT_GUARDED_BY(x) __attribute__((pt_guarded_by(x)))
+#else
+#define ABSL_PT_GUARDED_BY(x)
+#endif
 
 // ABSL_ACQUIRED_AFTER() / ABSL_ACQUIRED_BEFORE()
 //
@@ -103,11 +103,17 @@
 //
 //   Mutex m1_;
 //   Mutex m2_ ABSL_ACQUIRED_AFTER(m1_);
-#define ABSL_ACQUIRED_AFTER(...) \
-  ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(acquired_after(__VA_ARGS__))
+#if ABSL_HAVE_ATTRIBUTE(acquired_after)
+#define ABSL_ACQUIRED_AFTER(...) __attribute__((acquired_after(__VA_ARGS__)))
+#else
+#define ABSL_ACQUIRED_AFTER(...)
+#endif
 
-#define ABSL_ACQUIRED_BEFORE(...) \
-  ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(acquired_before(__VA_ARGS__))
+#if ABSL_HAVE_ATTRIBUTE(acquired_before)
+#define ABSL_ACQUIRED_BEFORE(...) __attribute__((acquired_before(__VA_ARGS__)))
+#else
+#define ABSL_ACQUIRED_BEFORE(...)
+#endif
 
 // ABSL_EXCLUSIVE_LOCKS_REQUIRED() / ABSL_SHARED_LOCKS_REQUIRED()
 //
@@ -132,20 +138,30 @@
 //
 //   void foo() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2) { ... }
 //   void bar() const ABSL_SHARED_LOCKS_REQUIRED(mu1, mu2) { ... }
-#define ABSL_EXCLUSIVE_LOCKS_REQUIRED(...)   \
-  ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE( \
-      exclusive_locks_required(__VA_ARGS__))
+#if ABSL_HAVE_ATTRIBUTE(exclusive_locks_required)
+#define ABSL_EXCLUSIVE_LOCKS_REQUIRED(...) \
+  __attribute__((exclusive_locks_required(__VA_ARGS__)))
+#else
+#define ABSL_EXCLUSIVE_LOCKS_REQUIRED(...)
+#endif
 
+#if ABSL_HAVE_ATTRIBUTE(shared_locks_required)
 #define ABSL_SHARED_LOCKS_REQUIRED(...) \
-  ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(shared_locks_required(__VA_ARGS__))
+  __attribute__((shared_locks_required(__VA_ARGS__)))
+#else
+#define ABSL_SHARED_LOCKS_REQUIRED(...)
+#endif
 
 // ABSL_LOCKS_EXCLUDED()
 //
 // Documents the locks acquired in the body of the function. These locks
 // cannot be held when calling this function (as Abseil's `Mutex` locks are
 // non-reentrant).
-#define ABSL_LOCKS_EXCLUDED(...) \
-  ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(locks_excluded(__VA_ARGS__))
+#if ABSL_HAVE_ATTRIBUTE(locks_excluded)
+#define ABSL_LOCKS_EXCLUDED(...) __attribute__((locks_excluded(__VA_ARGS__)))
+#else
+#define ABSL_LOCKS_EXCLUDED(...)
+#endif
 
 // ABSL_LOCK_RETURNED()
 //
@@ -153,8 +169,7 @@
 // a public getter method that returns a pointer to a private mutex should
 // be annotated with ABSL_LOCK_RETURNED.
 #if ABSL_HAVE_ATTRIBUTE(lock_returned)
-#define ABSL_LOCK_RETURNED(x) \
-  ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(lock_returned(x))
+#define ABSL_LOCK_RETURNED(x) __attribute__((lock_returned(x)))
 #else
 #define ABSL_LOCK_RETURNED(x)
 #endif
@@ -162,7 +177,11 @@
 // ABSL_LOCKABLE
 //
 // Documents if a class/type is a lockable type (such as the `Mutex` class).
-#define ABSL_LOCKABLE ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(lockable)
+#if ABSL_HAVE_ATTRIBUTE(lockable)
+#define ABSL_LOCKABLE __attribute__((lockable))
+#else
+#define ABSL_LOCKABLE
+#endif
 
 // ABSL_SCOPED_LOCKABLE
 //
@@ -171,30 +190,43 @@
 // acquired, and the destructor should use `UNLOCK_FUNCTION()` with no
 // arguments; the analysis will assume that the destructor unlocks whatever the
 // constructor locked.
-#define ABSL_SCOPED_LOCKABLE \
-  ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(scoped_lockable)
+#if ABSL_HAVE_ATTRIBUTE(scoped_lockable)
+#define ABSL_SCOPED_LOCKABLE __attribute__((scoped_lockable))
+#else
+#define ABSL_SCOPED_LOCKABLE
+#endif
 
 // ABSL_EXCLUSIVE_LOCK_FUNCTION()
 //
 // Documents functions that acquire a lock in the body of a function, and do
 // not release it.
-#define ABSL_EXCLUSIVE_LOCK_FUNCTION(...)    \
-  ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE( \
-      exclusive_lock_function(__VA_ARGS__))
+#if ABSL_HAVE_ATTRIBUTE(exclusive_lock_function)
+#define ABSL_EXCLUSIVE_LOCK_FUNCTION(...) \
+  __attribute__((exclusive_lock_function(__VA_ARGS__)))
+#else
+#define ABSL_EXCLUSIVE_LOCK_FUNCTION(...)
+#endif
 
 // ABSL_SHARED_LOCK_FUNCTION()
 //
 // Documents functions that acquire a shared (reader) lock in the body of a
 // function, and do not release it.
+#if ABSL_HAVE_ATTRIBUTE(shared_lock_function)
 #define ABSL_SHARED_LOCK_FUNCTION(...) \
-  ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(shared_lock_function(__VA_ARGS__))
+  __attribute__((shared_lock_function(__VA_ARGS__)))
+#else
+#define ABSL_SHARED_LOCK_FUNCTION(...)
+#endif
 
 // ABSL_UNLOCK_FUNCTION()
 //
 // Documents functions that expect a lock to be held on entry to the function,
 // and release it in the body of the function.
-#define ABSL_UNLOCK_FUNCTION(...) \
-  ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(unlock_function(__VA_ARGS__))
+#if ABSL_HAVE_ATTRIBUTE(unlock_function)
+#define ABSL_UNLOCK_FUNCTION(...) __attribute__((unlock_function(__VA_ARGS__)))
+#else
+#define ABSL_UNLOCK_FUNCTION(...)
+#endif
 
 // ABSL_EXCLUSIVE_TRYLOCK_FUNCTION() / ABSL_SHARED_TRYLOCK_FUNCTION()
 //
@@ -204,31 +236,49 @@
 // success, or `false` for functions that return `false` on success. The second
 // argument specifies the mutex that is locked on success. If unspecified, this
 // mutex is assumed to be `this`.
+#if ABSL_HAVE_ATTRIBUTE(exclusive_trylock_function)
 #define ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(...) \
-  ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE( \
-      exclusive_trylock_function(__VA_ARGS__))
+  __attribute__((exclusive_trylock_function(__VA_ARGS__)))
+#else
+#define ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(...)
+#endif
 
-#define ABSL_SHARED_TRYLOCK_FUNCTION(...)    \
-  ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE( \
-      shared_trylock_function(__VA_ARGS__))
+#if ABSL_HAVE_ATTRIBUTE(shared_trylock_function)
+#define ABSL_SHARED_TRYLOCK_FUNCTION(...) \
+  __attribute__((shared_trylock_function(__VA_ARGS__)))
+#else
+#define ABSL_SHARED_TRYLOCK_FUNCTION(...)
+#endif
 
 // ABSL_ASSERT_EXCLUSIVE_LOCK() / ABSL_ASSERT_SHARED_LOCK()
 //
 // Documents functions that dynamically check to see if a lock is held, and fail
 // if it is not held.
+#if ABSL_HAVE_ATTRIBUTE(assert_exclusive_lock)
 #define ABSL_ASSERT_EXCLUSIVE_LOCK(...) \
-  ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(assert_exclusive_lock(__VA_ARGS__))
+  __attribute__((assert_exclusive_lock(__VA_ARGS__)))
+#else
+#define ABSL_ASSERT_EXCLUSIVE_LOCK(...)
+#endif
 
+#if ABSL_HAVE_ATTRIBUTE(assert_shared_lock)
 #define ABSL_ASSERT_SHARED_LOCK(...) \
-  ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(assert_shared_lock(__VA_ARGS__))
+  __attribute__((assert_shared_lock(__VA_ARGS__)))
+#else
+#define ABSL_ASSERT_SHARED_LOCK(...)
+#endif
 
 // ABSL_NO_THREAD_SAFETY_ANALYSIS
 //
 // Turns off thread safety checking within the body of a particular function.
 // This annotation is used to mark functions that are known to be correct, but
 // the locking behavior is more complicated than the analyzer can handle.
+#if ABSL_HAVE_ATTRIBUTE(no_thread_safety_analysis)
 #define ABSL_NO_THREAD_SAFETY_ANALYSIS \
-  ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(no_thread_safety_analysis)
+  __attribute__((no_thread_safety_analysis))
+#else
+#define ABSL_NO_THREAD_SAFETY_ANALYSIS
+#endif
 
 //------------------------------------------------------------------------------
 // Tool-Supplied Annotations
diff --git a/absl/container/fixed_array_exception_safety_test.cc b/absl/container/fixed_array_exception_safety_test.cc
index a5bb009..e5f5929 100644
--- a/absl/container/fixed_array_exception_safety_test.cc
+++ b/absl/container/fixed_array_exception_safety_test.cc
@@ -150,8 +150,7 @@
 
 template <typename FixedArrT>
 testing::AssertionResult ReadMemory(FixedArrT* fixed_arr) {
-  // Marked volatile to prevent optimization. Used for running asan tests.
-  volatile int sum = 0;
+  int sum = 0;
   for (const auto& thrower : *fixed_arr) {
     sum += thrower.Get();
   }
diff --git a/absl/strings/internal/str_format/convert_test.cc b/absl/strings/internal/str_format/convert_test.cc
index 5ee5fbc..634ee78 100644
--- a/absl/strings/internal/str_format/convert_test.cc
+++ b/absl/strings/internal/str_format/convert_test.cc
@@ -1155,7 +1155,8 @@
         {__LINE__, StrPrint("%.12a", dx), "%.12a"},
     };
     if (native_traits.hex_float_uses_minimal_precision_when_not_specified) {
-      expect.push_back({__LINE__, StrPrint("%12a", dx), "%12a"});
+      Expectation ex = {__LINE__, StrPrint("%12a", dx), "%12a"};
+      expect.push_back(ex);
     }
     for (const Expectation &e : expect) {
       SCOPED_TRACE(e.line);
diff --git a/absl/synchronization/mutex.cc b/absl/synchronization/mutex.cc
index c7968f0..aafeb67 100644
--- a/absl/synchronization/mutex.cc
+++ b/absl/synchronization/mutex.cc
@@ -59,6 +59,7 @@
 
 using absl::base_internal::CurrentThreadIdentityIfPresent;
 using absl::base_internal::PerThreadSynch;
+using absl::base_internal::SchedulingGuard;
 using absl::base_internal::ThreadIdentity;
 using absl::synchronization_internal::GetOrCreateCurrentThreadIdentity;
 using absl::synchronization_internal::GraphCycles;
@@ -141,7 +142,9 @@
 namespace {
   enum DelayMode { AGGRESSIVE, GENTLE };
 };
-static int Delay(int32_t c, DelayMode mode) {
+
+namespace synchronization_internal {
+int MutexDelay(int32_t c, int mode) {
   // If this a uniprocessor, only yield/sleep.  Otherwise, if the mode is
   // aggressive then spin many times before yielding.  If the mode is
   // gentle then spin only a few times before yielding.  Aggressive spinning is
@@ -153,6 +156,7 @@
     // Spin.
     c++;
   } else {
+    SchedulingGuard::ScopedEnable enable_rescheduling;
     ABSL_TSAN_MUTEX_PRE_DIVERT(nullptr, 0);
     if (c == limit) {
       // Yield once.
@@ -167,6 +171,7 @@
   }
   return c;
 }
+}  // namespace synchronization_internal
 
 // --------------------------Generic atomic ops
 // Ensure that "(*pv & bits) == bits" by doing an atomic update of "*pv" to
@@ -1051,6 +1056,7 @@
 // Try to remove thread s from the list of waiters on this mutex.
 // Does nothing if s is not on the waiter list.
 void Mutex::TryRemove(PerThreadSynch *s) {
+  SchedulingGuard::ScopedDisable disable_rescheduling;
   intptr_t v = mu_.load(std::memory_order_relaxed);
   // acquire spinlock & lock
   if ((v & (kMuWait | kMuSpin | kMuWriter | kMuReader)) == kMuWait &&
@@ -1115,7 +1121,7 @@
       this->TryRemove(s);
       int c = 0;
       while (s->next != nullptr) {
-        c = Delay(c, GENTLE);
+        c = synchronization_internal::MutexDelay(c, GENTLE);
         this->TryRemove(s);
       }
       if (kDebugMode) {
@@ -1894,6 +1900,7 @@
 }
 
 void Mutex::LockSlowLoop(SynchWaitParams *waitp, int flags) {
+  SchedulingGuard::ScopedDisable disable_rescheduling;
   int c = 0;
   intptr_t v = mu_.load(std::memory_order_relaxed);
   if ((v & kMuEvent) != 0) {
@@ -1995,7 +2002,8 @@
     ABSL_RAW_CHECK(
         waitp->thread->waitp == nullptr || waitp->thread->suppress_fatal_errors,
         "detected illegal recursion into Mutex code");
-    c = Delay(c, GENTLE);          // delay, then try again
+    // delay, then try again
+    c = synchronization_internal::MutexDelay(c, GENTLE);
   }
   ABSL_RAW_CHECK(
       waitp->thread->waitp == nullptr || waitp->thread->suppress_fatal_errors,
@@ -2013,6 +2021,7 @@
 // or it is in the process of blocking on a condition variable; it must requeue
 // itself on the mutex/condvar to wait for its condition to become true.
 ABSL_ATTRIBUTE_NOINLINE void Mutex::UnlockSlow(SynchWaitParams *waitp) {
+  SchedulingGuard::ScopedDisable disable_rescheduling;
   intptr_t v = mu_.load(std::memory_order_relaxed);
   this->AssertReaderHeld();
   CheckForMutexCorruption(v, "Unlock");
@@ -2289,7 +2298,8 @@
       mu_.store(nv, std::memory_order_release);
       break;  // out of for(;;)-loop
     }
-    c = Delay(c, AGGRESSIVE);  // aggressive here; no one can proceed till we do
+    // aggressive here; no one can proceed till we do
+    c = synchronization_internal::MutexDelay(c, AGGRESSIVE);
   }                            // end of for(;;)-loop
 
   if (wake_list != kPerThreadSynchNull) {
@@ -2328,6 +2338,7 @@
 // It will later acquire the mutex with high probability.  Otherwise, we
 // enqueue thread w on this mutex.
 void Mutex::Fer(PerThreadSynch *w) {
+  SchedulingGuard::ScopedDisable disable_rescheduling;
   int c = 0;
   ABSL_RAW_CHECK(w->waitp->cond == nullptr,
                  "Mutex::Fer while waiting on Condition");
@@ -2377,7 +2388,7 @@
         return;
       }
     }
-    c = Delay(c, GENTLE);
+    c = synchronization_internal::MutexDelay(c, GENTLE);
   }
 }
 
@@ -2426,6 +2437,7 @@
 
 // Remove thread s from the list of waiters on this condition variable.
 void CondVar::Remove(PerThreadSynch *s) {
+  SchedulingGuard::ScopedDisable disable_rescheduling;
   intptr_t v;
   int c = 0;
   for (v = cv_.load(std::memory_order_relaxed);;
@@ -2454,7 +2466,8 @@
                 std::memory_order_release);
       return;
     } else {
-      c = Delay(c, GENTLE);            // try again after a delay
+      // try again after a delay
+      c = synchronization_internal::MutexDelay(c, GENTLE);
     }
   }
 }
@@ -2487,7 +2500,7 @@
          !cv_word->compare_exchange_weak(v, v | kCvSpin,
                                          std::memory_order_acquire,
                                          std::memory_order_relaxed)) {
-    c = Delay(c, GENTLE);
+    c = synchronization_internal::MutexDelay(c, GENTLE);
     v = cv_word->load(std::memory_order_relaxed);
   }
   ABSL_RAW_CHECK(waitp->thread->waitp == nullptr, "waiting when shouldn't be");
@@ -2586,6 +2599,7 @@
 }
 
 void CondVar::Signal() {
+  SchedulingGuard::ScopedDisable disable_rescheduling;
   ABSL_TSAN_MUTEX_PRE_SIGNAL(nullptr, 0);
   intptr_t v;
   int c = 0;
@@ -2618,7 +2632,7 @@
       ABSL_TSAN_MUTEX_POST_SIGNAL(nullptr, 0);
       return;
     } else {
-      c = Delay(c, GENTLE);
+      c = synchronization_internal::MutexDelay(c, GENTLE);
     }
   }
   ABSL_TSAN_MUTEX_POST_SIGNAL(nullptr, 0);
@@ -2655,7 +2669,8 @@
       ABSL_TSAN_MUTEX_POST_SIGNAL(nullptr, 0);
       return;
     } else {
-      c = Delay(c, GENTLE);           // try again after a delay
+      // try again after a delay
+      c = synchronization_internal::MutexDelay(c, GENTLE);
     }
   }
   ABSL_TSAN_MUTEX_POST_SIGNAL(nullptr, 0);
diff --git a/absl/time/internal/cctz/src/time_zone_info.cc b/absl/time/internal/cctz/src/time_zone_info.cc
index 665fb42..7ccda11 100644
--- a/absl/time/internal/cctz/src/time_zone_info.cc
+++ b/absl/time/internal/cctz/src/time_zone_info.cc
@@ -40,7 +40,6 @@
 #include <cstdlib>
 #include <cstring>
 #include <functional>
-#include <iostream>
 #include <memory>
 #include <sstream>
 #include <string>
@@ -83,6 +82,27 @@
     366 * kSecsPerDay,
 };
 
+// Convert a cctz::weekday to a POSIX TZ weekday number (0==Sun, ..., 6=Sat).
+inline int ToPosixWeekday(weekday wd) {
+  switch (wd) {
+    case weekday::sunday:
+      return 0;
+    case weekday::monday:
+      return 1;
+    case weekday::tuesday:
+      return 2;
+    case weekday::wednesday:
+      return 3;
+    case weekday::thursday:
+      return 4;
+    case weekday::friday:
+      return 5;
+    case weekday::saturday:
+      return 6;
+  }
+  return 0; /*NOTREACHED*/
+}
+
 // Single-byte, unsigned numeric values are encoded directly.
 inline std::uint_fast8_t Decode8(const char* cp) {
   return static_cast<std::uint_fast8_t>(*cp) & 0xff;
@@ -188,15 +208,13 @@
   tt.is_dst = false;
   tt.abbr_index = 0;
 
-  // We temporarily add some redundant, contemporary (2013 through 2023)
+  // We temporarily add some redundant, contemporary (2015 through 2025)
   // transitions for performance reasons.  See TimeZoneInfo::LocalTime().
   // TODO: Fix the performance issue and remove the extra transitions.
   transitions_.clear();
   transitions_.reserve(12);
   for (const std::int_fast64_t unix_time : {
-           -(1LL << 59),  // BIG_BANG
-           1356998400LL,  // 2013-01-01T00:00:00+00:00
-           1388534400LL,  // 2014-01-01T00:00:00+00:00
+           -(1LL << 59),  // a "first half" transition
            1420070400LL,  // 2015-01-01T00:00:00+00:00
            1451606400LL,  // 2016-01-01T00:00:00+00:00
            1483228800LL,  // 2017-01-01T00:00:00+00:00
@@ -206,7 +224,8 @@
            1609459200LL,  // 2021-01-01T00:00:00+00:00
            1640995200LL,  // 2022-01-01T00:00:00+00:00
            1672531200LL,  // 2023-01-01T00:00:00+00:00
-           2147483647LL,  // 2^31 - 1
+           1704067200LL,  // 2024-01-01T00:00:00+00:00
+           1735689600LL,  // 2025-01-01T00:00:00+00:00
        }) {
     Transition& tr(*transitions_.emplace(transitions_.end()));
     tr.unix_time = unix_time;
@@ -217,8 +236,8 @@
 
   default_transition_type_ = 0;
   abbreviations_ = FixedOffsetToAbbr(offset);
-  abbreviations_.append(1, '\0');  // add NUL
-  future_spec_.clear();            // never needed for a fixed-offset zone
+  abbreviations_.append(1, '\0');
+  future_spec_.clear();  // never needed for a fixed-offset zone
   extended_ = false;
 
   tt.civil_max = LocalTime(seconds::max().count(), tt).cs;
@@ -259,21 +278,6 @@
   return len;
 }
 
-// Check that the TransitionType has the expected offset/is_dst/abbreviation.
-void TimeZoneInfo::CheckTransition(const std::string& name,
-                                   const TransitionType& tt,
-                                   std::int_fast32_t offset, bool is_dst,
-                                   const std::string& abbr) const {
-  if (tt.utc_offset != offset || tt.is_dst != is_dst ||
-      &abbreviations_[tt.abbr_index] != abbr) {
-    std::clog << name << ": Transition"
-              << " offset=" << tt.utc_offset << "/"
-              << (tt.is_dst ? "DST" : "STD")
-              << "/abbr=" << &abbreviations_[tt.abbr_index]
-              << " does not match POSIX spec '" << future_spec_ << "'\n";
-  }
-}
-
 // zic(8) can generate no-op transitions when a zone changes rules at an
 // instant when there is actually no discontinuity.  So we check whether
 // two transitions have equivalent types (same offset/is_dst/abbr).
@@ -282,117 +286,108 @@
   if (tt1_index == tt2_index) return true;
   const TransitionType& tt1(transition_types_[tt1_index]);
   const TransitionType& tt2(transition_types_[tt2_index]);
-  if (tt1.is_dst != tt2.is_dst) return false;
   if (tt1.utc_offset != tt2.utc_offset) return false;
+  if (tt1.is_dst != tt2.is_dst) return false;
   if (tt1.abbr_index != tt2.abbr_index) return false;
   return true;
 }
 
+// Find/make a transition type with these attributes.
+bool TimeZoneInfo::GetTransitionType(std::int_fast32_t utc_offset, bool is_dst,
+                                     const std::string& abbr,
+                                     std::uint_fast8_t* index) {
+  std::size_t type_index = 0;
+  std::size_t abbr_index = abbreviations_.size();
+  for (; type_index != transition_types_.size(); ++type_index) {
+    const TransitionType& tt(transition_types_[type_index]);
+    const char* tt_abbr = &abbreviations_[tt.abbr_index];
+    if (tt_abbr == abbr) abbr_index = tt.abbr_index;
+    if (tt.utc_offset == utc_offset && tt.is_dst == is_dst) {
+      if (abbr_index == tt.abbr_index) break;  // reuse
+    }
+  }
+  if (type_index > 255 || abbr_index > 255) {
+    // No index space (8 bits) available for a new type or abbreviation.
+    return false;
+  }
+  if (type_index == transition_types_.size()) {
+    TransitionType& tt(*transition_types_.emplace(transition_types_.end()));
+    tt.utc_offset = static_cast<std::int_least32_t>(utc_offset);
+    tt.is_dst = is_dst;
+    if (abbr_index == abbreviations_.size()) {
+      abbreviations_.append(abbr);
+      abbreviations_.append(1, '\0');
+    }
+    tt.abbr_index = static_cast<std::uint_least8_t>(abbr_index);
+  }
+  *index = static_cast<std::uint_least8_t>(type_index);
+  return true;
+}
+
 // Use the POSIX-TZ-environment-variable-style string to handle times
 // in years after the last transition stored in the zoneinfo data.
-void TimeZoneInfo::ExtendTransitions(const std::string& name,
-                                     const Header& hdr) {
+bool TimeZoneInfo::ExtendTransitions() {
   extended_ = false;
-  bool extending = !future_spec_.empty();
+  if (future_spec_.empty()) return true;  // last transition prevails
 
   PosixTimeZone posix;
-  if (extending && !ParsePosixSpec(future_spec_, &posix)) {
-    std::clog << name << ": Failed to parse '" << future_spec_ << "'\n";
-    extending = false;
+  if (!ParsePosixSpec(future_spec_, &posix)) return false;
+
+  // Find transition type for the future std specification.
+  std::uint_fast8_t std_ti;
+  if (!GetTransitionType(posix.std_offset, false, posix.std_abbr, &std_ti))
+    return false;
+
+  if (posix.dst_abbr.empty()) {  // std only
+    // The future specification should match the last transition, and
+    // that means that handling the future will fall out naturally.
+    return EquivTransitions(transitions_.back().type_index, std_ti);
   }
 
-  if (extending && posix.dst_abbr.empty()) {  // std only
-    // The future specification should match the last/default transition,
-    // and that means that handling the future will fall out naturally.
-    std::uint_fast8_t index = default_transition_type_;
-    if (hdr.timecnt != 0) index = transitions_[hdr.timecnt - 1].type_index;
-    const TransitionType& tt(transition_types_[index]);
-    CheckTransition(name, tt, posix.std_offset, false, posix.std_abbr);
-    extending = false;
-  }
-
-  if (extending && hdr.timecnt < 2) {
-    std::clog << name << ": Too few transitions for POSIX spec\n";
-    extending = false;
-  }
-
-  if (!extending) {
-    // Ensure that there is always a transition in the second half of the
-    // time line (the BIG_BANG transition is in the first half) so that the
-    // signed difference between a civil_second and the civil_second of its
-    // previous transition is always representable, without overflow.
-    const Transition& last(transitions_.back());
-    if (last.unix_time < 0) {
-      const std::uint_fast8_t type_index = last.type_index;
-      Transition& tr(*transitions_.emplace(transitions_.end()));
-      tr.unix_time = 2147483647;  // 2038-01-19T03:14:07+00:00
-      tr.type_index = type_index;
-    }
-    return;  // last transition wins
-  }
+  // Find transition type for the future dst specification.
+  std::uint_fast8_t dst_ti;
+  if (!GetTransitionType(posix.dst_offset, true, posix.dst_abbr, &dst_ti))
+    return false;
 
   // Extend the transitions for an additional 400 years using the
   // future specification. Years beyond those can be handled by
   // mapping back to a cycle-equivalent year within that range.
-  // zic(8) should probably do this so that we don't have to.
-  // TODO: Reduce the extension by the number of compatible
-  // transitions already in place.
-  transitions_.reserve(hdr.timecnt + 400 * 2 + 1);
-  transitions_.resize(hdr.timecnt + 400 * 2);
+  // We may need two additional transitions for the current year.
+  transitions_.reserve(transitions_.size() + 400 * 2 + 2);
   extended_ = true;
 
-  // The future specification should match the last two transitions,
-  // and those transitions should have different is_dst flags.  Note
-  // that nothing says the UTC offset used by the is_dst transition
-  // must be greater than that used by the !is_dst transition.  (See
-  // Europe/Dublin, for example.)
-  const Transition* tr0 = &transitions_[hdr.timecnt - 1];
-  const Transition* tr1 = &transitions_[hdr.timecnt - 2];
-  const TransitionType* tt0 = &transition_types_[tr0->type_index];
-  const TransitionType* tt1 = &transition_types_[tr1->type_index];
-  const TransitionType& dst(tt0->is_dst ? *tt0 : *tt1);
-  const TransitionType& std(tt0->is_dst ? *tt1 : *tt0);
-  CheckTransition(name, dst, posix.dst_offset, true, posix.dst_abbr);
-  CheckTransition(name, std, posix.std_offset, false, posix.std_abbr);
-
-  // Add the transitions to tr1 and back to tr0 for each extra year.
-  last_year_ = LocalTime(tr0->unix_time, *tt0).cs.year();
+  const Transition& last(transitions_.back());
+  const std::int_fast64_t last_time = last.unix_time;
+  const TransitionType& last_tt(transition_types_[last.type_index]);
+  last_year_ = LocalTime(last_time, last_tt).cs.year();
   bool leap_year = IsLeap(last_year_);
-  const civil_day jan1(last_year_, 1, 1);
-  std::int_fast64_t jan1_time = civil_second(jan1) - civil_second();
-  int jan1_weekday = (static_cast<int>(get_weekday(jan1)) + 1) % 7;
-  Transition* tr = &transitions_[hdr.timecnt];  // next trans to fill
-  if (LocalTime(tr1->unix_time, *tt1).cs.year() != last_year_) {
-    // Add a single extra transition to align to a calendar year.
-    transitions_.resize(transitions_.size() + 1);
-    assert(tr == &transitions_[hdr.timecnt]);  // no reallocation
-    const PosixTransition& pt1(tt0->is_dst ? posix.dst_end : posix.dst_start);
-    std::int_fast64_t tr1_offset = TransOffset(leap_year, jan1_weekday, pt1);
-    tr->unix_time = jan1_time + tr1_offset - tt0->utc_offset;
-    tr++->type_index = tr1->type_index;
-    tr0 = &transitions_[hdr.timecnt];
-    tr1 = &transitions_[hdr.timecnt - 1];
-    tt0 = &transition_types_[tr0->type_index];
-    tt1 = &transition_types_[tr1->type_index];
-  }
-  const PosixTransition& pt1(tt0->is_dst ? posix.dst_end : posix.dst_start);
-  const PosixTransition& pt0(tt0->is_dst ? posix.dst_start : posix.dst_end);
-  for (const year_t limit = last_year_ + 400; last_year_ < limit;) {
-    last_year_ += 1;  // an additional year of generated transitions
+  const civil_second jan1(last_year_);
+  std::int_fast64_t jan1_time = jan1 - civil_second();
+  int jan1_weekday = ToPosixWeekday(get_weekday(jan1));
+
+  Transition dst = {0, dst_ti, civil_second(), civil_second()};
+  Transition std = {0, std_ti, civil_second(), civil_second()};
+  for (const year_t limit = last_year_ + 400;; ++last_year_) {
+    auto dst_trans_off = TransOffset(leap_year, jan1_weekday, posix.dst_start);
+    auto std_trans_off = TransOffset(leap_year, jan1_weekday, posix.dst_end);
+    dst.unix_time = jan1_time + dst_trans_off - posix.std_offset;
+    std.unix_time = jan1_time + std_trans_off - posix.dst_offset;
+    const auto* ta = dst.unix_time < std.unix_time ? &dst : &std;
+    const auto* tb = dst.unix_time < std.unix_time ? &std : &dst;
+    if (last_time < tb->unix_time) {
+      if (last_time < ta->unix_time) transitions_.push_back(*ta);
+      transitions_.push_back(*tb);
+    }
+    if (last_year_ == limit) break;
     jan1_time += kSecsPerYear[leap_year];
     jan1_weekday = (jan1_weekday + kDaysPerYear[leap_year]) % 7;
-    leap_year = !leap_year && IsLeap(last_year_);
-    std::int_fast64_t tr1_offset = TransOffset(leap_year, jan1_weekday, pt1);
-    tr->unix_time = jan1_time + tr1_offset - tt0->utc_offset;
-    tr++->type_index = tr1->type_index;
-    std::int_fast64_t tr0_offset = TransOffset(leap_year, jan1_weekday, pt0);
-    tr->unix_time = jan1_time + tr0_offset - tt1->utc_offset;
-    tr++->type_index = tr0->type_index;
+    leap_year = !leap_year && IsLeap(last_year_ + 1);
   }
-  assert(tr == &transitions_[0] + transitions_.size());
+
+  return true;
 }
 
-bool TimeZoneInfo::Load(const std::string& name, ZoneInfoSource* zip) {
+bool TimeZoneInfo::Load(ZoneInfoSource* zip) {
   // Read and validate the header.
   tzhead tzh;
   if (zip->Read(&tzh, sizeof(tzh)) != sizeof(tzh)) return false;
@@ -430,7 +425,7 @@
   const char* bp = tbuf.data();
 
   // Decode and validate the transitions.
-  transitions_.reserve(hdr.timecnt + 2);  // We might add a couple.
+  transitions_.reserve(hdr.timecnt + 2);
   transitions_.resize(hdr.timecnt);
   for (std::size_t i = 0; i != hdr.timecnt; ++i) {
     transitions_[i].unix_time = (time_len == 4) ? Decode32(bp) : Decode64(bp);
@@ -449,6 +444,7 @@
   }
 
   // Decode and validate the transition types.
+  transition_types_.reserve(hdr.typecnt + 2);
   transition_types_.resize(hdr.typecnt);
   for (std::size_t i = 0; i != hdr.typecnt; ++i) {
     transition_types_[i].utc_offset =
@@ -475,6 +471,7 @@
   }
 
   // Copy all the abbreviations.
+  abbreviations_.reserve(hdr.charcnt + 10);
   abbreviations_.assign(bp, hdr.charcnt);
   bp += hdr.charcnt;
 
@@ -525,19 +522,29 @@
   transitions_.resize(hdr.timecnt);
 
   // Ensure that there is always a transition in the first half of the
-  // time line (the second half is handled in ExtendTransitions()) so that
-  // the signed difference between a civil_second and the civil_second of
-  // its previous transition is always representable, without overflow.
-  // A contemporary zic will usually have already done this for us.
+  // time line (the second half is handled below) so that the signed
+  // difference between a civil_second and the civil_second of its
+  // previous transition is always representable, without overflow.
   if (transitions_.empty() || transitions_.front().unix_time >= 0) {
     Transition& tr(*transitions_.emplace(transitions_.begin()));
-    tr.unix_time = -(1LL << 59);  // see tz/zic.c "BIG_BANG"
+    tr.unix_time = -(1LL << 59);  // -18267312070-10-26T17:01:52+00:00
     tr.type_index = default_transition_type_;
-    hdr.timecnt += 1;
   }
 
   // Extend the transitions using the future specification.
-  ExtendTransitions(name, hdr);
+  if (!ExtendTransitions()) return false;
+
+  // Ensure that there is always a transition in the second half of the
+  // time line (the first half is handled above) so that the signed
+  // difference between a civil_second and the civil_second of its
+  // previous transition is always representable, without overflow.
+  const Transition& last(transitions_.back());
+  if (last.unix_time < 0) {
+    const std::uint_fast8_t type_index = last.type_index;
+    Transition& tr(*transitions_.emplace(transitions_.end()));
+    tr.unix_time = 2147483647;  // 2038-01-19T03:14:07+00:00
+    tr.type_index = type_index;
+  }
 
   // Compute the local civil time for each transition and the preceding
   // second. These will be used for reverse conversions in MakeTime().
@@ -723,7 +730,7 @@
         if (auto zip = AndroidZoneInfoSource::Open(name)) return zip;
         return nullptr;
       });
-  return zip != nullptr && Load(name, zip.get());
+  return zip != nullptr && Load(zip.get());
 }
 
 // BreakTime() translation for a particular transition type.
@@ -897,8 +904,8 @@
   const Transition* begin = &transitions_[0];
   const Transition* end = begin + transitions_.size();
   if (begin->unix_time <= -(1LL << 59)) {
-    // Do not report the BIG_BANG found in recent zoneinfo data as it is
-    // really a sentinel, not a transition.  See tz/zic.c.
+    // Do not report the BIG_BANG found in some zoneinfo data as it is
+    // really a sentinel, not a transition.  See pre-2018f tz/zic.c.
     ++begin;
   }
   std::int_fast64_t unix_time = ToUnixSeconds(tp);
@@ -923,8 +930,8 @@
   const Transition* begin = &transitions_[0];
   const Transition* end = begin + transitions_.size();
   if (begin->unix_time <= -(1LL << 59)) {
-    // Do not report the BIG_BANG found in recent zoneinfo data as it is
-    // really a sentinel, not a transition.  See tz/zic.c.
+    // Do not report the BIG_BANG found in some zoneinfo data as it is
+    // really a sentinel, not a transition.  See pre-2018f tz/zic.c.
     ++begin;
   }
   std::int_fast64_t unix_time = ToUnixSeconds(tp);
diff --git a/absl/time/internal/cctz/src/time_zone_info.h b/absl/time/internal/cctz/src/time_zone_info.h
index 2a10c06..068e34b 100644
--- a/absl/time/internal/cctz/src/time_zone_info.h
+++ b/absl/time/internal/cctz/src/time_zone_info.h
@@ -95,15 +95,14 @@
     std::size_t DataLength(std::size_t time_len) const;
   };
 
-  void CheckTransition(const std::string& name, const TransitionType& tt,
-                       std::int_fast32_t offset, bool is_dst,
-                       const std::string& abbr) const;
+  bool GetTransitionType(std::int_fast32_t utc_offset, bool is_dst,
+                         const std::string& abbr, std::uint_fast8_t* index);
   bool EquivTransitions(std::uint_fast8_t tt1_index,
                         std::uint_fast8_t tt2_index) const;
-  void ExtendTransitions(const std::string& name, const Header& hdr);
+  bool ExtendTransitions();
 
   bool ResetToBuiltinUTC(const seconds& offset);
-  bool Load(const std::string& name, ZoneInfoSource* zip);
+  bool Load(ZoneInfoSource* zip);
 
   // Helpers for BreakTime() and MakeTime().
   time_zone::absolute_lookup LocalTime(std::int_fast64_t unix_time,
diff --git a/ci/linux_clang-latest_libstdcxx_bazel.sh b/ci/linux_clang-latest_libstdcxx_bazel.sh
index 0192ee4..4e49067 100755
--- a/ci/linux_clang-latest_libstdcxx_bazel.sh
+++ b/ci/linux_clang-latest_libstdcxx_bazel.sh
@@ -71,15 +71,16 @@
         -e CC="/opt/llvm/clang/bin/clang" \
         -e BAZEL_COMPILER="llvm" \
         -e BAZEL_CXXOPTS="-std=${std}" \
-        -e CPLUS_INCLUDE_PATH="/usr/include/c++/8" \
         ${DOCKER_EXTRA_ARGS:-} \
         ${DOCKER_CONTAINER} \
         /usr/local/bin/bazel test ... \
           --compilation_mode="${compilation_mode}" \
+          --copt="--gcc-toolchain=/usr/local" \
           --copt="${exceptions_mode}" \
           --copt=-Werror \
           --define="absl=1" \
           --keep_going \
+          --linkopt="--gcc-toolchain=/usr/local" \
           --show_timestamps \
           --test_env="GTEST_INSTALL_FAILURE_SIGNAL_HANDLER=1" \
           --test_env="TZDIR=/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo" \
diff --git a/ci/linux_docker_containers.sh b/ci/linux_docker_containers.sh
index b652071..483ce2a 100644
--- a/ci/linux_docker_containers.sh
+++ b/ci/linux_docker_containers.sh
@@ -16,6 +16,6 @@
 # Test scripts should source this file to get the identifiers.
 
 readonly LINUX_ALPINE_CONTAINER="gcr.io/google.com/absl-177019/alpine:20191016"
-readonly LINUX_CLANG_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_clang-latest:20200706"
-readonly LINUX_GCC_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-latest:20200319"
+readonly LINUX_CLANG_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20200710"
+readonly LINUX_GCC_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20200710"
 readonly LINUX_GCC_49_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-4.9:20191018"