Roll abseil_revision 207ac6d88b..43e07c386b

Change Log:
https://chromium.googlesource.com/external/github.com/abseil/abseil-cpp/+log/207ac6d88b..43e07c386b
Full diff:
https://chromium.googlesource.com/external/github.com/abseil/abseil-cpp/+/207ac6d88b..43e07c386b

Bug: None
Change-Id: Ifeedecba95beae48e68db009f958f9b376644a1c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8244069
Commit-Queue: Danil Chapovalov <danilchap@chromium.org>
Reviewed-by: Mirko Bonadei <mbonadei@chromium.org>
Auto-Submit: Danil Chapovalov <danilchap@chromium.org>
Commit-Queue: Mirko Bonadei <mbonadei@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1677889}
NOKEYCHECK=True
GitOrigin-RevId: 9414218439bc77d8da173895acba229e46cef79a
diff --git a/README.chromium b/README.chromium
index 69f7629..98acc4a 100644
--- a/README.chromium
+++ b/README.chromium
@@ -4,7 +4,7 @@
 License: Apache-2.0
 License File: LICENSE
 Version: N/A
-Revision: 207ac6d88bea1bb0fd9652238f5e556147f44cb3
+Revision: 43e07c386b832bb4d1d29af61b7c45b59a54a38d
 Update Mechanism: Manual
 Security Critical: yes
 Shipped: yes
diff --git a/absl/base/casts.h b/absl/base/casts.h
index 1a85798..8aac0da 100644
--- a/absl/base/casts.h
+++ b/absl/base/casts.h
@@ -206,11 +206,11 @@
     const char* source_type, const char* target_type);
 
 template <typename To, typename From>
-inline void ValidateDownCast(From* f ABSL_ATTRIBUTE_UNUSED) {
+inline void ValidateDownCast(From* f) {
   // Assert only if RTTI is enabled and in debug mode or hardened asserts are
   // enabled.
-#ifdef ABSL_INTERNAL_HAS_RTTI
-#if !defined(NDEBUG) || (ABSL_OPTION_HARDENED == 1)
+#if defined(ABSL_INTERNAL_HAS_RTTI) && \
+    (!defined(NDEBUG) || (ABSL_OPTION_HARDENED == 1))
   // Suppress erroneous nonnull comparison warning on older GCC.
 #if defined(__GNUC__) && !defined(__clang__)
 #pragma GCC diagnostic push
@@ -223,7 +223,8 @@
     absl::base_internal::BadDownCastCrash(
         typeid(*f).name(), typeid(std::remove_pointer_t<To>).name());
   }
-#endif
+#else
+  (void)f;  // Denote this as "used" to avoid warning
 #endif
 }
 
diff --git a/absl/base/internal/cpu_detect.cc b/absl/base/internal/cpu_detect.cc
index 5275888..070cc86 100644
--- a/absl/base/internal/cpu_detect.cc
+++ b/absl/base/internal/cpu_detect.cc
@@ -350,31 +350,34 @@
 }
 
 bool SupportsArmCRC32PMULL() {
+  static const bool supported = []() {
   // Newer XNU kernels support querying all capabilities in a single
   // sysctlbyname.
 #if defined(CAP_BIT_CRC32) && defined(CAP_BIT_FEAT_PMULL)
-  static const std::optional<uint64_t> caps =
-      ReadSysctlByName<uint64_t>("hw.optional.arm.caps");
-  if (caps.has_value()) {
-    constexpr uint64_t kCrc32AndPmullCaps =
-        (uint64_t{1} << CAP_BIT_CRC32) | (uint64_t{1} << CAP_BIT_FEAT_PMULL);
-    return (*caps & kCrc32AndPmullCaps) == kCrc32AndPmullCaps;
-  }
+    const std::optional<uint64_t> caps =
+        ReadSysctlByName<uint64_t>("hw.optional.arm.caps");
+    if (caps.has_value()) {
+      constexpr uint64_t kCrc32AndPmullCaps =
+          (uint64_t{1} << CAP_BIT_CRC32) | (uint64_t{1} << CAP_BIT_FEAT_PMULL);
+      return (*caps & kCrc32AndPmullCaps) == kCrc32AndPmullCaps;
+    }
 #endif
 
-  // https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics#3915619
-  static const std::optional<int> armv8_crc32 =
-      ReadSysctlByName<int>("hw.optional.armv8_crc32");
-  if (armv8_crc32.value_or(0) == 0) {
-    return false;
-  }
-  // https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics#3918855
-  static const std::optional<int> feat_pmull =
-      ReadSysctlByName<int>("hw.optional.arm.FEAT_PMULL");
-  if (feat_pmull.value_or(0) == 0) {
-    return false;
-  }
-  return true;
+    // https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics#3915619
+    const std::optional<int> armv8_crc32 =
+        ReadSysctlByName<int>("hw.optional.armv8_crc32");
+    if (armv8_crc32.value_or(0) == 0) {
+      return false;
+    }
+    // https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics#3918855
+    const std::optional<int> feat_pmull =
+        ReadSysctlByName<int>("hw.optional.arm.FEAT_PMULL");
+    if (feat_pmull.value_or(0) == 0) {
+      return false;
+    }
+    return true;
+  }();
+  return supported;
 }
 
 bool SupportsBmi2() { return false; }
diff --git a/absl/crc/internal/crc32_x86_arm_combined_simd.h b/absl/crc/internal/crc32_x86_arm_combined_simd.h
index 07f5a69..9c287b5 100644
--- a/absl/crc/internal/crc32_x86_arm_combined_simd.h
+++ b/absl/crc/internal/crc32_x86_arm_combined_simd.h
@@ -107,6 +107,12 @@
 // Produces a XOR operation of |l| and |r|.
 V128 V128_Xor(const V128 l, const V128 r);
 
+// Produces a 3-way XOR operation of |a|, |b|, and |c|.
+// When `kUseEor3` is true, uses the ARMv8.2-A `EOR3` (3-way Exclusive-OR)
+// instruction.
+template <bool kUseEor3 = false>
+V128 V128_Xor3(const V128 a, const V128 b, const V128 c);
+
 // Sets the lower half of a 128 bit register to the given 64-bit value and
 // zeroes the upper half.
 // dst[63:0] := |r|
@@ -182,6 +188,11 @@
 
 inline V128 V128_Xor(const V128 l, const V128 r) { return _mm_xor_si128(l, r); }
 
+template <bool kUseEor3>
+inline V128 V128_Xor3(const V128 a, const V128 b, const V128 c) {
+  return V128_Xor(V128_Xor(a, b), c);
+}
+
 inline V128 V128_From64WithZeroFill(const uint64_t r) {
   return _mm_set_epi64x(static_cast<int64_t>(0), static_cast<int64_t>(r));
 }
@@ -266,6 +277,28 @@
 
 inline V128 V128_Xor(const V128 l, const V128 r) { return veorq_u64(l, r); }
 
+template <bool kUseEor3>
+inline V128 V128_Xor3(const V128 a, const V128 b, const V128 c) {
+#ifndef __ARM_FEATURE_SHA3
+  if constexpr (kUseEor3) {
+    // If the binary is compiled without SHA3 support, we need inline assembly
+    // to use the EOR3 instruction. We want to only use the below inline
+    // assembly block when both the CPU supports EOR3 and the binary is built
+    // without it, since we remove the sha3 extension support after the eor3
+    // instruction.
+    uint64x2_t res;
+    __asm__ __volatile__(
+        ".arch_extension sha3 \n\t"
+        "eor3 %0.16b, %1.16b, %2.16b, %3.16b \n\t"
+        ".arch_extension nosha3 \n\t"
+        : "=w"(res)
+        : "w"(a), "w"(b), "w"(c));
+    return res;
+  }
+#endif
+  return V128_Xor(V128_Xor(a, b), c);
+}
+
 inline V128 V128_From64WithZeroFill(const uint64_t r){
   constexpr uint64x2_t kZero = {0, 0};
   return vsetq_lane_u64(r, kZero, 0);
diff --git a/absl/crc/internal/crc_x86_arm_combined.cc b/absl/crc/internal/crc_x86_arm_combined.cc
index de2af4f..edffd36 100644
--- a/absl/crc/internal/crc_x86_arm_combined.cc
+++ b/absl/crc/internal/crc_x86_arm_combined.cc
@@ -40,7 +40,9 @@
 
 using ::absl::base_internal::CpuType;
 using ::absl::base_internal::GetCpuType;
+#if defined(__aarch64__)
 using ::absl::base_internal::SupportsArmCRC32PMULL;
+#endif
 
 #if defined(ABSL_INTERNAL_CAN_USE_SIMD_CRC32C)
 
@@ -218,6 +220,7 @@
   PCLMUL,
   VPCLMUL,
   NEON_PCLMUL,
+  NEON_PCLMUL_EOR3,
 };
 
 // Base class for CRC32AcceleratedX86ARMCombinedMultipleStreams containing the
@@ -234,6 +237,7 @@
   // https://www.intel.com/content/dam/www/public/us/en/documents/white-papers/fast-crc-computation-generic-polynomials-pclmulqdq-paper.pdf
   // We are applying it to CRC32C polynomial.
 #if defined(ABSL_CRC_INTERNAL_HAVE_ARM_SIMD)
+  template <bool kUseEor3 = false>
   ABSL_ATTRIBUTE_ALWAYS_INLINE void Process64BytesNeonPclmul(
       const uint8_t* p, V128* partialCRC) const {
     V128 loopMultiplicands =
@@ -256,14 +260,10 @@
     partialCRC2 = V128_PMulLow(partialCRC2, loopMultiplicands);
     partialCRC3 = V128_PMulLow(partialCRC3, loopMultiplicands);
     partialCRC4 = V128_PMulLow(partialCRC4, loopMultiplicands);
-    partialCRC1 = V128_Xor(tmp1, partialCRC1);
-    partialCRC2 = V128_Xor(tmp2, partialCRC2);
-    partialCRC3 = V128_Xor(tmp3, partialCRC3);
-    partialCRC4 = V128_Xor(tmp4, partialCRC4);
-    partialCRC1 = V128_Xor(partialCRC1, data1);
-    partialCRC2 = V128_Xor(partialCRC2, data2);
-    partialCRC3 = V128_Xor(partialCRC3, data3);
-    partialCRC4 = V128_Xor(partialCRC4, data4);
+    partialCRC1 = V128_Xor3<kUseEor3>(tmp1, partialCRC1, data1);
+    partialCRC2 = V128_Xor3<kUseEor3>(tmp2, partialCRC2, data2);
+    partialCRC3 = V128_Xor3<kUseEor3>(tmp3, partialCRC3, data3);
+    partialCRC4 = V128_Xor3<kUseEor3>(tmp4, partialCRC4, data4);
     partialCRC[0] = partialCRC1;
     partialCRC[1] = partialCRC2;
     partialCRC[2] = partialCRC3;
@@ -272,6 +272,7 @@
 
   // Reduce partialCRC produced by Process64BytesNeonPclmul into a single value,
   // that represents crc checksum of all the processed bytes.
+  template <bool kUseEor3 = false>
   ABSL_ATTRIBUTE_ALWAYS_INLINE uint64_t
   FinalizeNeonPclmulStream(V128* partialCRC) const {
     V128 partialCRC1 = partialCRC[0];
@@ -286,22 +287,19 @@
     V128 low = V128_PMulLow(reductionMultiplicands, partialCRC1);
     V128 high = V128_PMulHi(reductionMultiplicands, partialCRC1);
 
-    partialCRC1 = V128_Xor(low, high);
-    partialCRC1 = V128_Xor(partialCRC1, partialCRC3);
+    partialCRC1 = V128_Xor3<kUseEor3>(low, high, partialCRC3);
 
     low = V128_PMulLow(reductionMultiplicands, partialCRC2);
     high = V128_PMulHi(reductionMultiplicands, partialCRC2);
 
-    partialCRC2 = V128_Xor(low, high);
-    partialCRC2 = V128_Xor(partialCRC2, partialCRC4);
+    partialCRC2 = V128_Xor3<kUseEor3>(low, high, partialCRC4);
 
     reductionMultiplicands =
         V128_Load(reinterpret_cast<const V128*>(kFoldAcross128Bits));
 
     low = V128_PMulLow(reductionMultiplicands, partialCRC1);
     high = V128_PMulHi(reductionMultiplicands, partialCRC1);
-    V128 fullCRC = V128_Xor(low, high);
-    fullCRC = V128_Xor(fullCRC, partialCRC2);
+    V128 fullCRC = V128_Xor3<kUseEor3>(low, high, partialCRC2);
 
     // Reduce fullCRC into scalar value.
     uint32_t crc = 0;
@@ -393,9 +391,11 @@
     return crc;
   }
 
+  template <bool kUseEor3 = false>
   ABSL_ATTRIBUTE_ALWAYS_INLINE void Process64BytesNeonPclmul(const uint8_t*,
                                                              V128*) const {}
 
+  template <bool kUseEor3 = false>
   ABSL_ATTRIBUTE_ALWAYS_INLINE uint64_t FinalizeNeonPclmulStream(V128*) const {
     return 0;
   }
@@ -796,8 +796,12 @@
           V256_Broadcast128(reinterpret_cast<const V128*>(kFoldAcross512Bits));
       Process64BytesVpclmul(*pclmul_stream, reinterpret_cast<V256*>(partialCRC),
                             loopMultiplicands);
-    } else if constexpr (pclmul_stream_type == PclmulStreamType::NEON_PCLMUL) {
-      Process64BytesNeonPclmul(*pclmul_stream, partialCRC);
+    } else if constexpr (pclmul_stream_type == PclmulStreamType::NEON_PCLMUL ||
+                         pclmul_stream_type ==
+                             PclmulStreamType::NEON_PCLMUL_EOR3) {
+      constexpr bool kUseEor3 =
+          (pclmul_stream_type == PclmulStreamType::NEON_PCLMUL_EOR3);
+      Process64BytesNeonPclmul<kUseEor3>(*pclmul_stream, partialCRC);
     } else {
       Process64BytesPclmul(*pclmul_stream, partialCRC);
     }
@@ -808,8 +812,12 @@
   FinalizePclmulStream(V128* partialCRC) const {
     if constexpr (pclmul_stream_type == PclmulStreamType::VPCLMUL) {
       return FinalizeVpclmulStream(reinterpret_cast<V256*>(partialCRC));
-    } else if constexpr (pclmul_stream_type == PclmulStreamType::NEON_PCLMUL) {
-      return FinalizeNeonPclmulStream(partialCRC);
+    } else if constexpr (pclmul_stream_type == PclmulStreamType::NEON_PCLMUL ||
+                         pclmul_stream_type ==
+                             PclmulStreamType::NEON_PCLMUL_EOR3) {
+      constexpr bool kUseEor3 =
+          (pclmul_stream_type == PclmulStreamType::NEON_PCLMUL_EOR3);
+      return FinalizeNeonPclmulStream<kUseEor3>(partialCRC);
     } else {
       return CRC32AcceleratedX86ARMCombinedMultipleStreamsBase::
           FinalizePclmulStream(partialCRC);
@@ -869,18 +877,20 @@
       return new CRC32AcceleratedX86ARMCombinedMultipleStreams<
           3, 0, PclmulStreamType::PCLMUL>();
     case CpuType::kArmNeoverseN1:
-    case CpuType::kArmNeoverseN2:
     case CpuType::kArmNeoverseV1:
+      return new CRC32AcceleratedX86ARMCombinedMultipleStreams<
+          1, 1, PclmulStreamType::NEON_PCLMUL>();
+    case CpuType::kArmNeoverseN2:
     case CpuType::kArmNeoverseN3:
     case CpuType::kNvidiaGrace:
       return new CRC32AcceleratedX86ARMCombinedMultipleStreams<
-          1, 1, PclmulStreamType::NEON_PCLMUL>();
+          1, 1, PclmulStreamType::NEON_PCLMUL_EOR3>();
     case CpuType::kAmpereSiryn:
       return new CRC32AcceleratedX86ARMCombinedMultipleStreams<
-          3, 2, PclmulStreamType::NEON_PCLMUL>();
+          3, 2, PclmulStreamType::NEON_PCLMUL_EOR3>();
     case CpuType::kArmNeoverseV2:
       return new CRC32AcceleratedX86ARMCombinedMultipleStreams<
-          1, 2, PclmulStreamType::NEON_PCLMUL>();
+          1, 2, PclmulStreamType::NEON_PCLMUL_EOR3>();
 #if defined(__aarch64__)
     default:
       // Not all ARM processors support the needed instructions, so check here
diff --git a/absl/debugging/symbolize_test.cc b/absl/debugging/symbolize_test.cc
index 2862394..d216f26 100644
--- a/absl/debugging/symbolize_test.cc
+++ b/absl/debugging/symbolize_test.cc
@@ -244,8 +244,8 @@
 }
 
 static int GetStackConsumptionUpperLimit() {
-  // Symbolize stack consumption should be within 2kB.
-  int stack_consumption_upper_limit = 2048;
+  // Symbolize stack consumption should be within 4kB.
+  int stack_consumption_upper_limit = 4096;
 #if defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
     defined(ABSL_HAVE_MEMORY_SANITIZER) || defined(ABSL_HAVE_THREAD_SANITIZER)
   // Account for sanitizer instrumentation requiring additional stack space.
diff --git a/absl/profiling/internal/exponential_biased_test.cc b/absl/profiling/internal/exponential_biased_test.cc
index ebfbcad..3dcf105 100644
--- a/absl/profiling/internal/exponential_biased_test.cc
+++ b/absl/profiling/internal/exponential_biased_test.cc
@@ -132,6 +132,49 @@
   printf("Heads = %d (%f%%)\n", heads, 100.0 * heads / 10000000);
 }
 
+// In simplified idealized world, `GetSkipCount(m) == 0` translates to
+// `-log(X) * m + B <= 1/2`, where X is a uniform random number in (0, 1],
+// and B is uniform random number in [-0.5, 0.5). Let U = 0.5 - B, that makes
+// U a uniform random number in (0, 1]. After exponentiation we get
+// `X >= exp(-U / m)`. Probability of this is `1 - exp(-U / m)`, so we have to
+// integrate for all possible values of U: `1 - m * (1 - exp(-1 / m))`. For
+// simplicity take just two terms of Taylor series expansion:
+// `1/(2*m) - 1/(6*m^2)`. Reciprocal of that is `2*m + 2/3 + O(1/m)`. If we use
+// more math tricks we can get "exact" approximation, but result will still be
+// `2*m + 2/3 + O(1/m)`.
+TEST(ExponentialBiasedTest, OnePerNDemoWithGetSkipCount) {
+  ExponentialBiased eb;
+  int n = 22;
+  int rounds = 220000;
+  int hits = 0;
+  for (int i = 0; i < rounds; i++) {
+    if (eb.GetSkipCount(n / 2) == 0) ++hits;
+  }
+  double inverse_hit_rate = rounds / static_cast<double>(hits);
+  printf("N = %d, rounds = %d, inverse hit rate = %f (should be ~= N + 0.67)\n",
+         n, rounds, inverse_hit_rate);
+}
+
+// Large requested mean flattens density function near zero, making it almost
+// linear.
+TEST(ExponentialBiasedTest, OneOfNDemoWithGetSkipCount) {
+  ExponentialBiased eb;
+  int n = 6;
+  int large_mean = 10000000;
+  int rounds = n * 10000;
+  std::vector<int> hits(static_cast<size_t>(n), 0);
+  for (int i = 0; i < rounds; i++) {
+    int64_t v = eb.GetSkipCount(large_mean);
+    int64_t a = v % n;
+    ++hits[static_cast<size_t>(a)];
+  }
+  printf("N = %d, rounds = %d, mean = %d\n", n, rounds, large_mean);
+  for (int i = 0; i < n; i++) {
+    printf("  inverse hit rate for %d: %f (should be ~= N)\n", i,
+           rounds / static_cast<double>(hits[static_cast<size_t>(i)]));
+  }
+}
+
 TEST(ExponentialBiasedTest, SampleDemoWithStride) {
   ExponentialBiased eb;
   int64_t stride = eb.GetStride(10);
diff --git a/absl/status/internal/status_internal.h b/absl/status/internal/status_internal.h
index 767f88f..03b0663 100644
--- a/absl/status/internal/status_internal.h
+++ b/absl/status/internal/status_internal.h
@@ -73,6 +73,7 @@
 class StatusPrivateAccessorForStatusBuilder;
 #endif  // !SWIG
 
+#ifndef SWIG
 // Container for status payloads.
 struct Payload {
   std::string type_url;
@@ -91,6 +92,7 @@
         message_(message_arg),
         payloads_(std::move(payloads_arg)) {}
 
+#ifndef SWIG
   template <typename String,
             typename = std::enable_if_t<std::is_same_v<String, std::string>>>
   StatusRep(absl::StatusCode code_arg, String&& message_arg,
@@ -99,6 +101,7 @@
         code_(code_arg),
         message_(std::forward<String>(message_arg)),
         payloads_(std::move(payloads_arg)) {}
+#endif  // SWIG
 
   absl::StatusCode code() const { return code_; }
   const std::string& message() const { return message_; }
@@ -172,6 +175,7 @@
     const absl::Status* absl_nonnull status, const char* absl_nonnull prefix);
 
 }  // namespace status_internal
+#endif  // SWIG
 
 ABSL_NAMESPACE_END
 }  // namespace absl
diff --git a/absl/status/status.cc b/absl/status/status.cc
index 2d3ccc0..155c5d8 100644
--- a/absl/status/status.cc
+++ b/absl/status/status.cc
@@ -130,11 +130,13 @@
   return MakeStatusRepImpl<absl::string_view>(inlined_rep, msg, loc);
 }
 
+#ifndef SWIG
 uintptr_t Status::MakeRepFromStringRvalue(uintptr_t inlined_rep,
                                           std::string&& msg,
                                           absl::SourceLocation loc) {
   return MakeStatusRepImpl<std::string&&>(inlined_rep, std::move(msg), loc);
 }
+#endif  // SWIG
 
 uintptr_t Status::AddSourceLocationImpl(uintptr_t rep,
                                         absl::SourceLocation loc) {
diff --git a/absl/status/status.h b/absl/status/status.h
index 10e22d6..3103e79 100644
--- a/absl/status/status.h
+++ b/absl/status/status.h
@@ -75,6 +75,10 @@
 namespace absl {
 ABSL_NAMESPACE_BEGIN
 
+#ifndef SWIG  // SWIG chokes on enum class
+// The following canonical error codes should always be in sync with
+// https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto.
+
 // absl::StatusCode
 //
 // An `absl::StatusCode` is an enumerated type indicating either no error ("OK")
@@ -352,6 +356,7 @@
   lhs = lhs ^ rhs;
   return lhs;
 }
+#endif  // SWIG
 
 // absl::Status
 //
@@ -460,6 +465,7 @@
   Status(absl::StatusCode code, absl::string_view msg,
          absl::SourceLocation loc = SourceLocation::current());
 
+#ifndef SWIG
   // Same as above but for rvalue string.
   // Note: using a template to disambiguate the case of matching string_view and
   // string&& (e.g. char*) as a template lowers the priority of the overload.
@@ -467,6 +473,7 @@
             typename = std::enable_if_t<std::is_same_v<String, std::string>>>
   Status(absl::StatusCode code, String&& msg,
          absl::SourceLocation loc = SourceLocation::current());
+#endif  // SWIG
 
   // Create a status from a `base_status` and a `loc`. The `loc` will be
   // appended to the location chain of the new status, iff the `base_status` is
@@ -475,19 +482,23 @@
       : Status(base_status) {
     AddSourceLocation(loc);
   }
+#ifndef SWIG
   Status(Status&& base_status, absl::SourceLocation loc)
       : Status(std::move(base_status)) {
     AddSourceLocation(loc);
   }
+#endif  // SWIG
 
   Status(const Status&);
   Status& operator=(const Status& x);
 
+#ifndef SWIG
   // Move operators
 
   // The moved-from state is valid but unspecified.
   Status(Status&&) noexcept;
   Status& operator=(Status&&) noexcept;
+#endif  // SWIG
 
   ~Status();
 
@@ -507,7 +518,9 @@
   //   overall_status.Update(new_status);
   //
   void Update(const Status& new_status);
+#ifndef SWIG
   void Update(Status&& new_status);
+#endif  // SWIG
 
   // Status::ok()
   //
@@ -533,6 +546,8 @@
   // wire format. Use `Status::code()` for error handling.
   int raw_code() const;
 
+#ifndef SWIG
+
   // Status::message()
   //
   // Returns the error message associated with this error code, if available.
@@ -540,10 +555,15 @@
   // for the error message to be the empty string. As a result, prefer
   // `operator<<` or `Status::ToString()` for debug logging.
   absl::string_view message() const;
+#endif  // SWIG
 
   friend bool operator==(const Status&, const Status&);
   friend bool operator!=(const Status&, const Status&);
 
+#ifndef SWIG
+  // `ToString` has stubs in SWIG to remain backward compatible with the old
+  // format by calling `util::StatusToString`, to save migration cost.
+
   // Status::ToString()
   //
   // Returns a string based on the `mode`. By default, it returns combination of
@@ -563,6 +583,7 @@
   friend void AbslStringify(Sink& sink, const Status& status) {
     sink.Append(status.ToString(StatusToStringMode::kWithEverything));
   }
+#endif  // SWIG
 
   // Status::IgnoreError()
   //
@@ -574,7 +595,11 @@
   // swap()
   //
   // Swap the contents of one status with another.
+#ifndef SWIG
   friend void swap(Status& a, Status& b) noexcept;
+#else
+  friend void swap(Status& a, Status& b);
+#endif  // SWIG
 
   //----------------------------------------------------------------------------
   // Payload Management APIs
@@ -639,9 +664,14 @@
   //
   // NOTE: Any mutation on the same 'absl::Status' object during visitation is
   // forbidden and could result in undefined behavior.
+  // FunctionRef doesn't work nicely with Swig.
+  // TODO(b/189736749): Consider making this available once FunctionRef is
+  // supported.
+#ifndef SWIG
   void ForEachPayload(
       absl::FunctionRef<void(absl::string_view, const absl::Cord&)> visitor)
       const;
+#endif  // SWIG
 
   absl::Span<const absl::SourceLocation> GetSourceLocations() const {
     if (IsInlined(rep_)) return {};
@@ -661,6 +691,8 @@
     ABSL_ASSUME(!okay);
   }
 
+#ifndef SWIG
+
   // Status::WithSourceLocation()
   //
   // Returns a copy of the current status, with `loc` appended to its location
@@ -695,6 +727,7 @@
     AddSourceLocation(loc);
     return std::move(*this);
   }
+#endif  // SWIG
 
  private:
   friend Status CancelledError();
@@ -722,10 +755,12 @@
                                          absl::string_view msg,
                                          absl::SourceLocation loc);
 
+#ifndef SWIG
   // Same as above but for rvalue string.
   static uintptr_t MakeRepFromStringRvalue(uintptr_t inlined_rep,
                                            std::string&& msg,
                                            absl::SourceLocation loc);
+#endif  // SWIG
 
   template <typename StringOrView>
   friend uintptr_t MakeStatusRepImpl(uintptr_t inlined_rep, StringOrView msg,
@@ -920,11 +955,13 @@
                       absl::SourceLocation loc)
     : Status(MakeRepFromStringView(CodeToInlinedRep(code), msg, loc)) {}
 
+#ifndef SWIG
 template <typename String, typename>
 inline Status::Status(absl::StatusCode code, String&& msg,
                       absl::SourceLocation loc)
     : Status(MakeRepFromStringRvalue(CodeToInlinedRep(code),
                                      std::forward<String>(msg), loc)) {}
+#endif  // SWIG
 
 inline Status::Status(const Status& x) : Status(x.rep_) { Ref(rep_); }
 
@@ -938,6 +975,7 @@
   return *this;
 }
 
+#ifndef SWIG
 inline Status::Status(Status&& x) noexcept : Status(x.rep_) {
   x.rep_ = MovedFromRep();
 }
@@ -951,6 +989,7 @@
   }
   return *this;
 }
+#endif  // SWIG
 
 inline void Status::Update(const Status& new_status) {
   if (ok()) {
@@ -958,11 +997,13 @@
   }
 }
 
+#ifndef SWIG
 inline void Status::Update(Status&& new_status) {
   if (ok()) {
     *this = std::move(new_status);
   }
 }
+#endif  // SWIG
 
 inline Status::~Status() { Unref(rep_); }
 
@@ -1005,10 +1046,17 @@
   // no-op
 }
 
+#ifndef SWIG
 inline void swap(absl::Status& a, absl::Status& b) noexcept {
   using std::swap;
   swap(a.rep_, b.rep_);
 }
+#else
+inline void swap(absl::Status& a, absl::Status& b) {
+  using std::swap;
+  swap(a.rep_, b.rep_);
+}
+#endif  // SWIG
 
 inline std::optional<absl::Cord> Status::GetPayload(
     absl::string_view type_url) const {
@@ -1074,7 +1122,9 @@
   if (!IsInlined(rep)) RepToPointer(rep)->Unref();
 }
 
+#ifndef SWIG
 inline Status OkStatus() { return Status(); }
+#endif  // SWIG
 
 // Creates a `Status` object with the `absl::StatusCode::kCancelled` error code
 // and an empty message. It is provided only for efficiency, given that
@@ -1095,6 +1145,7 @@
 template <int error_code>
 Status MakeErrorImpl(string_view message, SourceLocation loc);
 // Make the instantiations extern to reduce bloat on callers.
+#ifndef SWIG
 extern template Status MakeErrorImpl<0>(string_view, SourceLocation);
 extern template Status MakeErrorImpl<1>(string_view, SourceLocation);
 extern template Status MakeErrorImpl<2>(string_view, SourceLocation);
@@ -1112,6 +1163,7 @@
 extern template Status MakeErrorImpl<14>(string_view, SourceLocation);
 extern template Status MakeErrorImpl<15>(string_view, SourceLocation);
 extern template Status MakeErrorImpl<16>(string_view, SourceLocation);
+#endif  // SWIG
 
 template <StatusCode error_code>
 Status MakeError(string_view message, SourceLocation loc) {
diff --git a/absl/status/status_builder.h b/absl/status/status_builder.h
index 60b7562..55ab7a8 100644
--- a/absl/status/status_builder.h
+++ b/absl/status/status_builder.h
@@ -704,13 +704,13 @@
 // would prevent use of operator<<.  For example:
 //
 //   ABSL_RETURN_IF_ERROR(foo(val))
-//       .With(util::ExtraMessage("when calling foo()"))
+//       .With(absl::ExtraMessage("when calling foo()"))
 //       .With(util::TaskReturn(task));
 //
 // or
 //
 //   ABSL_RETURN_IF_ERROR(foo(val))
-//       .With(util::ExtraMessage() << "val: " << val)
+//       .With(absl::ExtraMessage() << "val: " << val)
 //       .With(util::TaskReturn(task));
 //
 // Note in the above example, the ABSL_RETURN_IF_ERROR macro ensures the
diff --git a/absl/status/statusor.h b/absl/status/statusor.h
index 2ee7947..3d7f8c4 100644
--- a/absl/status/statusor.h
+++ b/absl/status/statusor.h
@@ -61,6 +61,7 @@
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
+#ifndef SWIG
 
 // BadStatusOrAccess
 //
@@ -111,8 +112,10 @@
   mutable absl::once_flag init_what_;
   mutable std::string what_;
 };
+#endif  // !SWIG
 
 // Returned StatusOr objects may not be ignored.
+#ifndef SWIG
 template <typename T>
 #if ABSL_HAVE_CPP_ATTRIBUTE(nodiscard)
 // TODO(b/176172494): ABSL_MUST_USE_RESULT should expand to the more strict
@@ -121,6 +124,7 @@
 #else
 class ABSL_MUST_USE_RESULT StatusOr;
 #endif  // ABSL_HAVE_CPP_ATTRIBUTE(nodiscard)
+#endif  // !SWIG
 
 // absl::StatusOr<T>
 //
@@ -233,6 +237,8 @@
   // assignable.
   StatusOr& operator=(const StatusOr&) = default;
 
+#ifndef SWIG
+
   // `StatusOr<T>` is move constructible if `T` is move constructible.
   StatusOr(StatusOr&&) = default;
   // `StatusOr<T>` is moveAssignable if `T` is move constructible and move
@@ -454,6 +460,8 @@
   explicit StatusOr(U&& u ABSL_ATTRIBUTE_LIFETIME_BOUND)  // NOLINT
       : StatusOr(std::in_place, std::forward<U>(u)) {}
 
+#endif  // SWIG
+
   // StatusOr<T>::ok()
   //
   // Returns whether or not this `absl::StatusOr<T>` holds a `T` value. This
@@ -475,8 +483,12 @@
   // Returns a reference to the current `absl::Status` contained within the
   // `absl::StatusOr<T>`. If `absl::StatusOr<T>` contains a `T`, then this
   // function returns `absl::OkStatus()`.
+#ifdef SWIG
+  ABSL_MUST_USE_RESULT const absl::Status& status() const;
+#else  // SWIG
   ABSL_MUST_USE_RESULT const Status& status() const&;
   Status status() &&;
+#endif  // SWIG
 
   absl::Span<const absl::SourceLocation> GetSourceLocations() const {
     return this->status_.GetSourceLocations();
@@ -488,6 +500,8 @@
     this->status_.AddSourceLocation(loc);
   }
 
+#ifndef SWIG
+
   // StatusOr<T>::WithSourceLocation()
   //
   // Appends the `loc` to the current location chain inside the status iff the
@@ -507,6 +521,7 @@
     AddSourceLocation(loc);
     return std::move(*this);
   }
+#endif  // SWIG
 
   // StatusOr<T>::value()
   //
@@ -534,7 +549,13 @@
   //
   // The `std::move` on statusor instead of on the whole expression enables
   // warnings about possible uses of the statusor object after the move.
+#ifdef SWIG
+  const T& value() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
+#else  // SWIG
   using StatusOr::OperatorBase::value;
+#endif  // SWIG
+
+#ifndef SWIG
 
   // StatusOr<T>:: operator*()
   //
@@ -598,6 +619,7 @@
   T value_or(U&& default_value ABSL_ATTRIBUTE_LIFETIME_BOUND) && {
     return std::move(*this).ValueOrImpl(std::forward<U>(default_value));
   }
+#endif  // SWIG
 
   // StatusOr<T>::IgnoreError()
   //
@@ -606,6 +628,8 @@
   // the floor.
   void IgnoreError() const;
 
+#ifndef SWIG
+
   // StatusOr<T>::emplace()
   //
   // Reconstructs the inner value T in-place using the provided args, using the
@@ -658,13 +682,16 @@
   // In optimized builds, passing absl::OkStatus() here will have the effect
   // of passing absl::StatusCode::kInternal as a fallback.
   using internal_statusor::StatusOrData<T>::AssignStatus;
+#endif  // SWIG
 
  private:
+#ifndef SWIG
   using internal_statusor::StatusOrData<T>::Assign;
   template <typename U>
   void Assign(const absl::StatusOr<U>& other);
   template <typename U>
   void Assign(absl::StatusOr<U>&& other);
+#endif  // SWIG
 };
 
 // operator==()
@@ -722,6 +749,7 @@
   }
 }
 
+#ifndef SWIG
 //------------------------------------------------------------------------------
 // Implementation details for StatusOr<T>
 //------------------------------------------------------------------------------
@@ -774,6 +802,8 @@
   // no-op
 }
 
+#endif  // SWIG
+
 ABSL_NAMESPACE_END
 }  // namespace absl
 
diff --git a/absl/time/internal/cctz/src/time_zone_info.cc b/absl/time/internal/cctz/src/time_zone_info.cc
index f7ed379..1f8f46a 100644
--- a/absl/time/internal/cctz/src/time_zone_info.cc
+++ b/absl/time/internal/cctz/src/time_zone_info.cc
@@ -426,17 +426,25 @@
 #endif
 }
 
+// Returns true if c separates path components. Windows accepts either
+// form, so a "..\" component walks up a directory just like a "../" one.
+inline bool IsPathSeparator(char c) {
+#if defined(_WIN32)
+  return c == '/' || c == '\\';
+#else
+  return c == '/';
+#endif
+}
+
 // Returns true if the zone name starting at pos contains an unsafe path.
-inline bool UnsafePath(const std::string& name, std::size_t pos) {
-  // Path traversal: exact match ".."
-  if (name.compare(pos, std::string::npos, "..") == 0) return true;
-  // Path traversal: leading component "../"
-  if (name.compare(pos, 3, "../") == 0) return true;
-  // Path traversal: interior component "/../"
-  if (name.find("/../", pos) != std::string::npos) return true;
-  // Path traversal: trailing component "/.."
-  if (name.size() - pos >= 3 && name.compare(name.size() - 3, 3, "/..") == 0) {
-    return true;
+bool UnsafePath(const std::string& name, std::size_t pos) {
+  // Path traversal: a ".." component that is at the beginning or preceded
+  // by a separator, and at the end or followed by a separator.
+  for (auto i = pos; (i = name.find("..", i)) != std::string::npos; i += 2) {
+    if ((i == pos || IsPathSeparator(name[i - 1])) &&
+        (i == name.size() - 2 || IsPathSeparator(name[i + 2]))) {
+      return true;
+    }
   }
   return false;
 }
@@ -748,11 +756,6 @@
     if (transitions_[i].unix_time < -(1LL << 59) ||
         transitions_[i].unix_time > (1LL << 59))
       return false;  // out of range
-    if (i != 0) {
-      // Check that the transitions are ordered by time (as zic guarantees).
-      if (!Transition::ByUnixTime()(transitions_[i - 1], transitions_[i]))
-        return false;  // out of order
-    }
   }
   bool seen_type_0 = false;
   for (std::size_t i = 0; i != hdr.timecnt; ++i) {
@@ -867,11 +870,13 @@
     ttp = &transition_types_[tr.type_index];
     tr.civil_sec = LocalTime(tr.unix_time, *ttp).cs;
     if (i != 0) {
-      // Check that the transitions are ordered by civil time. Essentially
-      // this means that an offset change cannot cross another such change.
-      // No one does this in practice, and we depend on it in MakeTime().
-      if (!Transition::ByCivilTime()(transitions_[i - 1], tr))
+      // Check that offset changes don't cross each other. No one
+      // does this in practice, and we depend on increasing absolute
+      // and civil times in BreakTime() and MakeTime() respectively.
+      if (!Transition::ByUnixTime()(transitions_[i - 1], tr) ||
+          !Transition::ByCivilTime()(transitions_[i - 1], tr)) {
         return false;  // out of order
+      }
     }
   }
 
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 1147e93..f53ac03 100644
--- a/absl/time/internal/cctz/src/time_zone_lookup_test.cc
+++ b/absl/time/internal/cctz/src/time_zone_lookup_test.cc
@@ -187,12 +187,6 @@
   EXPECT_EQ(chrono::system_clock::from_time_t(0),
             convert(civil_second(1970, 1, 1, 0, 0, 0), tz));  // UTC
 
-  // Reject path-traversal components.
-  EXPECT_FALSE(load_time_zone("file:../etc/passwd", &tz));
-  EXPECT_FALSE(load_time_zone("file:../../etc/passwd", &tz));
-  EXPECT_FALSE(load_time_zone("file:/../etc/passwd", &tz));
-  EXPECT_FALSE(load_time_zone("file:America/../America/Los_Angeles", &tz));
-
   // Reject a fixed-offset name with a NUL where a digit belongs.
   for (const int i : {10, 11, 13, 14, 16, 17}) {
     std::string name = "Fixed/UTC+00:00:00";
@@ -200,10 +194,28 @@
     EXPECT_FALSE(load_time_zone(name, &tz)) << "NUL at offset " << i;
   }
 
-  // Reject non-regular files and directories.
+  // Reject path-traversal components.
+  EXPECT_FALSE(load_time_zone("file:../etc/passwd", &tz));
+  EXPECT_FALSE(load_time_zone("file:../../etc/passwd", &tz));
+  EXPECT_FALSE(load_time_zone("file:/../etc/passwd", &tz));
+  EXPECT_FALSE(load_time_zone("file:America/../America/Los_Angeles", &tz));
+
+#if defined(_WIN32)
+  // Windows accepts '\' as a path separator, so these escape as well.
+  // If they were admitted, the second would resolve back into the zoneinfo
+  // directory and load, failing the test. Elsewhere '\' is an ordinary
+  // filename character, so these would only fail as nonexistent names.
+  EXPECT_FALSE(load_time_zone("file:..\\etc\\passwd", &tz));
+  EXPECT_FALSE(load_time_zone("file:America\\..\\America/Los_Angeles", &tz));
+#endif
+
+#if !defined(_MSC_VER)
+  // Reject non-regular files and directories. The check lives in the
+  // non-MSVC FOpen(), so only expect it there.
   EXPECT_FALSE(load_time_zone("file:/dev/null", &tz));
   EXPECT_FALSE(load_time_zone("file:/dev/stdin", &tz));
   EXPECT_FALSE(load_time_zone("file:/tmp", &tz));
+#endif
 }
 
 TEST(TimeZone, Equality) {
@@ -1060,6 +1072,15 @@
         new StringZoneInfoSource(MakeExtendedTzif(
             0, -5 * 3600, std::string{"EST", 4}, "EST5EDT,M3.2.0,M11.1.0")));
   }
+  if (name == "test:ExtendedOverlappingRules") {
+    // The daylight time of one year starts more than four days after its
+    // nominal date, while the next year's ends more than five days before
+    // its own, so the two years' generated transitions overlap.
+    return std::unique_ptr<ZoneInfoSource>(
+        new StringZoneInfoSource(MakeExtendedTzif(
+            0, -5 * 3600, std::string{"STD", 4},
+            "STD-12:00:00DST12:00:00,358/100:00:00,1/-139:00:00")));
+  }
   if (name == "test:UnterminatedAbbreviation") {
     // The abbreviation area is missing its final NUL, so the abbreviation
     // would run into whatever ExtendTransitions() appends behind it.
@@ -1094,6 +1115,20 @@
   cctz_extension::zone_info_source_factory = prev_factory;
 }
 
+// A transition time may include a day offset of up to +/-167 hours, so the
+// rules for consecutive years can overlap, producing transitions that go
+// backward in unix time. BreakTime() binary searches the transitions by
+// unix time, so such a zone must be rejected.
+TEST(TimeZoneEdgeCase, ExtendedOverlappingRules) {
+  auto prev_factory = cctz_extension::zone_info_source_factory;
+  cctz_extension::zone_info_source_factory = ExtendedTestFactory;
+
+  time_zone tz;
+  EXPECT_FALSE(load_time_zone("test:ExtendedOverlappingRules", &tz));
+
+  cctz_extension::zone_info_source_factory = prev_factory;
+}
+
 // Looking up the maximum time in an extended zone must fold back through the
 // 400-year cycle without overflowing when BreakTime() computes the shift.
 TEST(TimeZoneEdgeCase, ExtendedFarFuture) {