Roll abseil_revision 8e088c5f3c..c1aa431c07

Change Log:
https://chromium.googlesource.com/external/github.com/abseil/abseil-cpp/+log/8e088c5f3c..c1aa431c07
Full diff:
https://chromium.googlesource.com/external/github.com/abseil/abseil-cpp/+/8e088c5f3c..c1aa431c07

Bug: None
Change-Id: Ie675c4fb16f0cf2253fd53951925afaf7f480812
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3103207
Reviewed-by: Mirko Bonadei <mbonadei@chromium.org>
Commit-Queue: Danil Chapovalov <danilchap@chromium.org>
Cr-Commit-Position: refs/heads/master@{#912980}
NOKEYCHECK=True
GitOrigin-RevId: 639151e0e7bb4b313250de50e9ed2606cf08cba6
diff --git a/BUILD.gn b/BUILD.gn
index c0b4715..9b45e3f 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -186,6 +186,7 @@
         "absl/base:config_test",
         "absl/cleanup:cleanup_test",
         "absl/container:inlined_vector_test",
+        "absl/hash:low_level_hash_test",
         "absl/memory:memory_test",
         "absl/meta:type_traits_test",
         "absl/status:statusor_test",
diff --git a/CMake/AbseilDll.cmake b/CMake/AbseilDll.cmake
index 8bdf5a5..ea45c8a 100644
--- a/CMake/AbseilDll.cmake
+++ b/CMake/AbseilDll.cmake
@@ -124,8 +124,8 @@
   "hash/internal/hash.h"
   "hash/internal/hash.cc"
   "hash/internal/spy_hash_state.h"
-  "hash/internal/wyhash.h"
-  "hash/internal/wyhash.cc"
+  "hash/internal/low_level_hash.h"
+  "hash/internal/low_level_hash.cc"
   "memory/memory.h"
   "meta/type_traits.h"
   "numeric/bits.h"
diff --git a/README.chromium b/README.chromium
index 74d1e95..829c002 100644
--- a/README.chromium
+++ b/README.chromium
@@ -4,7 +4,7 @@
 License: Apache 2.0
 License File: LICENSE
 Version: 0
-Revision: 8e088c5f3c290c5ac53dd5010fd501d80b483115
+Revision: c1aa431c071af43d7935bc0d44d560ea851a7696
 Security Critical: yes
 
 Description:
diff --git a/WORKSPACE b/WORKSPACE
index f4a5c47..af30787 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -42,3 +42,11 @@
     strip_prefix = "rules_cc-daf6ace7cfeacd6a83e9ff2ed659f416537b6c74",
     urls = ["https://github.com/bazelbuild/rules_cc/archive/daf6ace7cfeacd6a83e9ff2ed659f416537b6c74.zip"],
 )
+
+# Bazel platform rules.
+http_archive(
+    name = "platforms",
+    sha256 = "b601beaf841244de5c5a50d2b2eddd34839788000fa1be4260ce6603ca0d8eb7",
+    strip_prefix = "platforms-98939346da932eef0b54cf808622f5bb0928f00b",
+    urls = ["https://github.com/bazelbuild/platforms/archive/98939346da932eef0b54cf808622f5bb0928f00b.zip"],
+)
diff --git a/absl/BUILD.bazel b/absl/BUILD.bazel
index c9d4a2d..7239b5b 100644
--- a/absl/BUILD.bazel
+++ b/absl/BUILD.bazel
@@ -44,14 +44,14 @@
 config_setting(
     name = "osx",
     constraint_values = [
-        "@bazel_tools//platforms:osx",
+        "@platforms//os:osx",
     ],
 )
 
 config_setting(
     name = "ios",
     constraint_values = [
-        "@bazel_tools//platforms:ios",
+        "@platforms//os:ios",
     ],
 )
 
diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel
index f22fdc6..cf55f4b 100644
--- a/absl/container/BUILD.bazel
+++ b/absl/container/BUILD.bazel
@@ -598,7 +598,6 @@
         ":hashtable_debug_hooks",
         ":hashtablez_sampler",
         ":have_sse",
-        ":layout",
         "//absl/base:config",
         "//absl/base:core_headers",
         "//absl/base:endian",
diff --git a/absl/container/BUILD.gn b/absl/container/BUILD.gn
index 3e4c68d..ba939ae 100644
--- a/absl/container/BUILD.gn
+++ b/absl/container/BUILD.gn
@@ -218,7 +218,6 @@
     ":hashtable_debug_hooks",
     ":hashtablez_sampler",
     ":have_sse",
-    ":layout",
     "//third_party/abseil-cpp/absl/base:config",
     "//third_party/abseil-cpp/absl/base:core_headers",
     "//third_party/abseil-cpp/absl/base:endian",
diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt
index 91c4015..691a05c 100644
--- a/absl/container/CMakeLists.txt
+++ b/absl/container/CMakeLists.txt
@@ -666,7 +666,6 @@
     absl::hash_policy_traits
     absl::hashtable_debug_hooks
     absl::have_sse
-    absl::layout
     absl::memory
     absl::meta
     absl::optional
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h
index bafafd4..ade2f58 100644
--- a/absl/container/internal/raw_hash_set.h
+++ b/absl/container/internal/raw_hash_set.h
@@ -112,7 +112,6 @@
 #include "absl/container/internal/hashtable_debug_hooks.h"
 #include "absl/container/internal/hashtablez_sampler.h"
 #include "absl/container/internal/have_sse.h"
-#include "absl/container/internal/layout.h"
 #include "absl/memory/memory.h"
 #include "absl/meta/type_traits.h"
 #include "absl/numeric/bits.h"
@@ -625,6 +624,20 @@
   SetCtrl(i, static_cast<ctrl_t>(h), capacity, ctrl, slot, slot_size);
 }
 
+// The allocated block consists of `capacity + 1 + NumClonedBytes()` control
+// bytes followed by `capacity` slots, which must be aligned to `slot_align`.
+// SlotOffset returns the offset of the slots into the allocated block.
+inline size_t SlotOffset(size_t capacity, size_t slot_align) {
+  assert(IsValidCapacity(capacity));
+  const size_t num_control_bytes = capacity + 1 + NumClonedBytes();
+  return (num_control_bytes + slot_align - 1) & (~slot_align + 1);
+}
+
+// Returns the size of the allocated block. See also above comment.
+inline size_t AllocSize(size_t capacity, size_t slot_size, size_t slot_align) {
+  return SlotOffset(capacity, slot_align) + capacity * slot_size;
+}
+
 // Policy: a policy defines how to perform different operations on
 // the slots of the hashtable (see hash_policy_traits.h for the full interface
 // of policy).
@@ -681,15 +694,6 @@
   auto KeyTypeCanBeHashed(const Hash& h, const key_type& k) -> decltype(h(k));
   auto KeyTypeCanBeEq(const Eq& eq, const key_type& k) -> decltype(eq(k, k));
 
-  using Layout = absl::container_internal::Layout<ctrl_t, slot_type>;
-
-  static Layout MakeLayout(size_t capacity) {
-    assert(IsValidCapacity(capacity));
-    // The extra control bytes are for 1 sentinel byte followed by
-    // NumClonedBytes() bytes that are cloned from the beginning.
-    return Layout(capacity + 1 + NumClonedBytes(), capacity);
-  }
-
   using AllocTraits = absl::allocator_traits<allocator_type>;
   using SlotAlloc = typename absl::allocator_traits<
       allocator_type>::template rebind_alloc<slot_type>;
@@ -1610,11 +1614,12 @@
       infoz() = Sample();
     }
 
-    auto layout = MakeLayout(capacity_);
-    char* mem = static_cast<char*>(
-        Allocate<Layout::Alignment()>(&alloc_ref(), layout.AllocSize()));
-    ctrl_ = layout.template Pointer<0>(mem);
-    slots_ = layout.template Pointer<1>(mem);
+    char* mem = static_cast<char*>(Allocate<alignof(slot_type)>(
+        &alloc_ref(),
+        AllocSize(capacity_, sizeof(slot_type), alignof(slot_type))));
+    ctrl_ = reinterpret_cast<ctrl_t*>(mem);
+    slots_ = reinterpret_cast<slot_type*>(
+        mem + SlotOffset(capacity_, alignof(slot_type)));
     ResetCtrl(capacity_, ctrl_, slots_, sizeof(slot_type));
     reset_growth_left();
     infoz().RecordStorageChanged(size_, capacity_);
@@ -1627,10 +1632,11 @@
         PolicyTraits::destroy(&alloc_ref(), slots_ + i);
       }
     }
-    auto layout = MakeLayout(capacity_);
     // Unpoison before returning the memory to the allocator.
     SanitizerUnpoisonMemoryRegion(slots_, sizeof(slot_type) * capacity_);
-    Deallocate<Layout::Alignment()>(&alloc_ref(), ctrl_, layout.AllocSize());
+    Deallocate<alignof(slot_type)>(
+        &alloc_ref(), ctrl_,
+        AllocSize(capacity_, sizeof(slot_type), alignof(slot_type)));
     ctrl_ = EmptyGroup();
     slots_ = nullptr;
     size_ = 0;
@@ -1661,9 +1667,9 @@
     if (old_capacity) {
       SanitizerUnpoisonMemoryRegion(old_slots,
                                     sizeof(slot_type) * old_capacity);
-      auto layout = MakeLayout(old_capacity);
-      Deallocate<Layout::Alignment()>(&alloc_ref(), old_ctrl,
-                                      layout.AllocSize());
+      Deallocate<alignof(slot_type)>(
+          &alloc_ref(), old_ctrl,
+          AllocSize(old_capacity, sizeof(slot_type), alignof(slot_type)));
     }
     infoz().RecordRehash(total_probe_length);
   }
@@ -1948,8 +1954,7 @@
   static size_t AllocatedByteSize(const Set& c) {
     size_t capacity = c.capacity_;
     if (capacity == 0) return 0;
-    auto layout = Set::MakeLayout(capacity);
-    size_t m = layout.AllocSize();
+    size_t m = AllocSize(capacity, sizeof(Slot), alignof(Slot));
 
     size_t per_slot = Traits::space_used(static_cast<const Slot*>(nullptr));
     if (per_slot != ~size_t{}) {
@@ -1967,8 +1972,8 @@
   static size_t LowerBoundAllocatedByteSize(size_t size) {
     size_t capacity = GrowthToLowerboundCapacity(size);
     if (capacity == 0) return 0;
-    auto layout = Set::MakeLayout(NormalizeCapacity(capacity));
-    size_t m = layout.AllocSize();
+    size_t m =
+        AllocSize(NormalizeCapacity(capacity), sizeof(Slot), alignof(Slot));
     size_t per_slot = Traits::space_used(static_cast<const Slot*>(nullptr));
     if (per_slot != ~size_t{}) {
       m += per_slot * size;
diff --git a/absl/debugging/internal/demangle.cc b/absl/debugging/internal/demangle.cc
index 5cd5632..93ae327 100644
--- a/absl/debugging/internal/demangle.cc
+++ b/absl/debugging/internal/demangle.cc
@@ -1617,6 +1617,7 @@
 //              ::= <2-ary operator-name> <expression> <expression>
 //              ::= <3-ary operator-name> <expression> <expression> <expression>
 //              ::= cl <expression>+ E
+//              ::= cp <simple-id> <expression>* E # Clang-specific.
 //              ::= cv <type> <expression>      # type (expression)
 //              ::= cv <type> _ <expression>* E # type (expr-list)
 //              ::= st <type>
@@ -1639,14 +1640,23 @@
     return true;
   }
 
-  // Object/function call expression.
   ParseState copy = state->parse_state;
+
+  // Object/function call expression.
   if (ParseTwoCharToken(state, "cl") && OneOrMore(ParseExpression, state) &&
       ParseOneCharToken(state, 'E')) {
     return true;
   }
   state->parse_state = copy;
 
+  // Clang-specific "cp <simple-id> <expression>* E"
+  //   https://clang.llvm.org/doxygen/ItaniumMangle_8cpp_source.html#l04338
+  if (ParseTwoCharToken(state, "cp") && ParseSimpleId(state) &&
+      ZeroOrMore(ParseExpression, state) && ParseOneCharToken(state, 'E')) {
+    return true;
+  }
+  state->parse_state = copy;
+
   // Function-param expression (level 0).
   if (ParseTwoCharToken(state, "fp") && Optional(ParseCVQualifiers(state)) &&
       Optional(ParseNumber(state, nullptr)) && ParseOneCharToken(state, '_')) {
diff --git a/absl/debugging/internal/stack_consumption.cc b/absl/debugging/internal/stack_consumption.cc
index e3dd51c..5134864 100644
--- a/absl/debugging/internal/stack_consumption.cc
+++ b/absl/debugging/internal/stack_consumption.cc
@@ -43,7 +43,7 @@
 // unspecified. Therefore, instead we hardcode the direction of the
 // stack on platforms we know about.
 #if defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || \
-    defined(__aarch64__)
+    defined(__aarch64__) || defined(__riscv)
 constexpr bool kStackGrowsDown = true;
 #else
 #error Need to define kStackGrowsDown
diff --git a/absl/debugging/internal/stack_consumption.h b/absl/debugging/internal/stack_consumption.h
index 2b5e715..f41b64c 100644
--- a/absl/debugging/internal/stack_consumption.h
+++ b/absl/debugging/internal/stack_consumption.h
@@ -26,7 +26,7 @@
 #error ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION cannot be set directly
 #elif !defined(__APPLE__) && !defined(_WIN32) &&                     \
     (defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || \
-     defined(__aarch64__))
+     defined(__aarch64__) || defined(__riscv))
 #define ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION 1
 
 namespace absl {
diff --git a/absl/debugging/internal/symbolize.h b/absl/debugging/internal/symbolize.h
index 8c296f8..27d5e65 100644
--- a/absl/debugging/internal/symbolize.h
+++ b/absl/debugging/internal/symbolize.h
@@ -28,8 +28,8 @@
 
 #ifdef ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE
 #error ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE cannot be directly set
-#elif defined(__ELF__) && defined(__GLIBC__) && !defined(__native_client__) && \
-    !defined(__asmjs__) && !defined(__wasm__)
+#elif defined(__ELF__) && defined(__GLIBC__) && !defined(__native_client__) \
+      && !defined(__asmjs__) && !defined(__wasm__)
 #define ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE 1
 
 #include <elf.h>
diff --git a/absl/flags/internal/usage.cc b/absl/flags/internal/usage.cc
index a883567..949709e 100644
--- a/absl/flags/internal/usage.cc
+++ b/absl/flags/internal/usage.cc
@@ -17,7 +17,6 @@
 
 #include <stdint.h>
 
-#include <algorithm>
 #include <functional>
 #include <map>
 #include <ostream>
@@ -256,6 +255,9 @@
       matching_flags;
 
   flags_internal::ForEachFlag([&](absl::CommandLineFlag& flag) {
+    // Ignore retired flags.
+    if (flag.IsRetired()) return;
+
     // If the flag has been stripped, pretend that it doesn't exist.
     if (flag.Help() == flags_internal::kStrippedFlagHelp) return;
 
@@ -273,14 +275,6 @@
   absl::string_view file_separator;     // controls blank lines between files
   for (auto& package : matching_flags) {
     if (format == HelpFormat::kHumanReadable) {
-      // Hide packages with only retired flags
-      bool all_package_flags_are_retired = true;
-      for (const auto& flags_in_file : package.second) {
-        for (const auto* flag : flags_in_file.second) {
-          all_package_flags_are_retired &= flag->IsRetired();
-        }
-      }
-      if (all_package_flags_are_retired) continue;
       out << package_separator;
       package_separator = "\n\n";
     }
@@ -340,11 +334,8 @@
 // Produces the help message describing specific flag.
 void FlagHelp(std::ostream& out, const CommandLineFlag& flag,
               HelpFormat format) {
-  if (format == HelpFormat::kHumanReadable) {
-    // Ignore retired flags
-    if (flag.IsRetired()) return;
+  if (format == HelpFormat::kHumanReadable)
     flags_internal::FlagHelpHumanReadable(flag, out);
-  }
 }
 
 // --------------------------------------------------------------------
diff --git a/absl/flags/internal/usage_test.cc b/absl/flags/internal/usage_test.cc
index 5055640..044d71c 100644
--- a/absl/flags/internal/usage_test.cc
+++ b/absl/flags/internal/usage_test.cc
@@ -61,9 +61,6 @@
     "Even more long long long long long long long long long long long long "
     "help message.");
 
-ABSL_RETIRED_FLAG(int64_t, usage_reporting_test_flag_07, 1,
-                  "usage_reporting_test_flag_07 help message");
-
 namespace {
 
 namespace flags = absl::flags_internal;
diff --git a/absl/hash/BUILD.bazel b/absl/hash/BUILD.bazel
index 4b2c220..21915cc 100644
--- a/absl/hash/BUILD.bazel
+++ b/absl/hash/BUILD.bazel
@@ -37,7 +37,7 @@
     linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":city",
-        ":wyhash",
+        ":low_level_hash",
         "//absl/base:config",
         "//absl/base:core_headers",
         "//absl/base:endian",
@@ -143,9 +143,9 @@
 )
 
 cc_library(
-    name = "wyhash",
-    srcs = ["internal/wyhash.cc"],
-    hdrs = ["internal/wyhash.h"],
+    name = "low_level_hash",
+    srcs = ["internal/low_level_hash.cc"],
+    hdrs = ["internal/low_level_hash.h"],
     copts = ABSL_DEFAULT_COPTS,
     linkopts = ABSL_DEFAULT_LINKOPTS,
     visibility = ["//visibility:private"],
@@ -157,13 +157,13 @@
 )
 
 cc_test(
-    name = "wyhash_test",
-    srcs = ["internal/wyhash_test.cc"],
+    name = "low_level_hash_test",
+    srcs = ["internal/low_level_hash_test.cc"],
     copts = ABSL_TEST_COPTS,
     linkopts = ABSL_DEFAULT_LINKOPTS,
     visibility = ["//visibility:private"],
     deps = [
-        ":wyhash",
+        ":low_level_hash",
         "//absl/strings",
         "@com_google_googletest//:gtest_main",
     ],
diff --git a/absl/hash/BUILD.gn b/absl/hash/BUILD.gn
index 3e239b4..0962de6 100644
--- a/absl/hash/BUILD.gn
+++ b/absl/hash/BUILD.gn
@@ -13,7 +13,7 @@
   public = [ "hash.h" ]
   deps = [
     ":city",
-    ":wyhash",
+    ":low_level_hash",
     "//third_party/abseil-cpp/absl/base:config",
     "//third_party/abseil-cpp/absl/base:core_headers",
     "//third_party/abseil-cpp/absl/base:endian",
@@ -60,9 +60,9 @@
   ]
 }
 
-absl_source_set("wyhash") {
-  public = [ "internal/wyhash.h" ]
-  sources = [ "internal/wyhash.cc" ]
+absl_source_set("low_level_hash") {
+  public = [ "internal/low_level_hash.h" ]
+  sources = [ "internal/low_level_hash.cc" ]
   deps = [
     "//third_party/abseil-cpp/absl/base:config",
     "//third_party/abseil-cpp/absl/base:endian",
@@ -70,3 +70,14 @@
   ]
   visibility = [ ":*" ]
 }
+
+absl_source_set("low_level_hash_test") {
+  testonly = true
+  sources = [ "internal/low_level_hash_test.cc" ]
+  deps = [
+    ":low_level_hash",
+    "//third_party/abseil-cpp/absl/strings",
+    "//third_party/googletest:gtest",
+    "//third_party/googletest:gmock",
+  ]
+}
diff --git a/absl/hash/CMakeLists.txt b/absl/hash/CMakeLists.txt
index c82f66f..6c79c93 100644
--- a/absl/hash/CMakeLists.txt
+++ b/absl/hash/CMakeLists.txt
@@ -36,7 +36,7 @@
     absl::optional
     absl::variant
     absl::utility
-    absl::wyhash
+    absl::low_level_hash
   PUBLIC
 )
 
@@ -118,11 +118,11 @@
 
 absl_cc_library(
   NAME
-    wyhash
+    low_level_hash
   HDRS
-    "internal/wyhash.h"
+    "internal/low_level_hash.h"
   SRCS
-    "internal/wyhash.cc"
+    "internal/low_level_hash.cc"
   COPTS
     ${ABSL_DEFAULT_COPTS}
   DEPS
@@ -133,13 +133,13 @@
 
 absl_cc_test(
   NAME
-    wyhash_test
+    low_level_hash_test
   SRCS
-    "internal/wyhash_test.cc"
+    "internal/low_level_hash_test.cc"
   COPTS
     ${ABSL_TEST_COPTS}
   DEPS
-    absl::wyhash
+    absl::low_level_hash
     absl::strings
     GTest::gmock_main
 )
diff --git a/absl/hash/internal/hash.cc b/absl/hash/internal/hash.cc
index 06f53a5..4b81891 100644
--- a/absl/hash/internal/hash.cc
+++ b/absl/hash/internal/hash.cc
@@ -46,21 +46,22 @@
 
 ABSL_CONST_INIT const void* const MixingHashState::kSeed = &kSeed;
 
-// The salt array used by Wyhash. This array is NOT the mechanism used to make
-// absl::Hash non-deterministic between program invocations.  See `Seed()` for
-// that mechanism.
+// The salt array used by LowLevelHash. This array is NOT the mechanism used to
+// make absl::Hash non-deterministic between program invocations.  See `Seed()`
+// for that mechanism.
 //
 // Any random values are fine. These values are just digits from the decimal
 // part of pi.
 // https://en.wikipedia.org/wiki/Nothing-up-my-sleeve_number
-constexpr uint64_t kWyhashSalt[5] = {
+constexpr uint64_t kHashSalt[5] = {
     uint64_t{0x243F6A8885A308D3}, uint64_t{0x13198A2E03707344},
     uint64_t{0xA4093822299F31D0}, uint64_t{0x082EFA98EC4E6C89},
     uint64_t{0x452821E638D01377},
 };
 
-uint64_t MixingHashState::WyhashImpl(const unsigned char* data, size_t len) {
-  return Wyhash(data, len, Seed(), kWyhashSalt);
+uint64_t MixingHashState::LowLevelHashImpl(const unsigned char* data,
+                                           size_t len) {
+  return LowLevelHash(data, len, Seed(), kHashSalt);
 }
 
 }  // namespace hash_internal
diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h
index 90627e0..f517409 100644
--- a/absl/hash/internal/hash.h
+++ b/absl/hash/internal/hash.h
@@ -42,7 +42,7 @@
 #include "absl/base/internal/unaligned_access.h"
 #include "absl/base/port.h"
 #include "absl/container/fixed_array.h"
-#include "absl/hash/internal/wyhash.h"
+#include "absl/hash/internal/low_level_hash.h"
 #include "absl/meta/type_traits.h"
 #include "absl/numeric/int128.h"
 #include "absl/strings/string_view.h"
@@ -874,14 +874,14 @@
     return static_cast<uint64_t>(m ^ (m >> (sizeof(m) * 8 / 2)));
   }
 
-  // An extern to avoid bloat on a direct call to Wyhash() with fixed values for
-  // both the seed and salt parameters.
-  static uint64_t WyhashImpl(const unsigned char* data, size_t len);
+  // An extern to avoid bloat on a direct call to LowLevelHash() with fixed
+  // values for both the seed and salt parameters.
+  static uint64_t LowLevelHashImpl(const unsigned char* data, size_t len);
 
   ABSL_ATTRIBUTE_ALWAYS_INLINE static uint64_t Hash64(const unsigned char* data,
                                                       size_t len) {
 #ifdef ABSL_HAVE_INTRINSIC_INT128
-    return WyhashImpl(data, len);
+    return LowLevelHashImpl(data, len);
 #else
     return absl::hash_internal::CityHash64(reinterpret_cast<const char*>(data), len);
 #endif
@@ -945,8 +945,8 @@
 inline uint64_t MixingHashState::CombineContiguousImpl(
     uint64_t state, const unsigned char* first, size_t len,
     std::integral_constant<int, 8> /* sizeof_size_t */) {
-  // For large values we use Wyhash or CityHash depending on the platform, for
-  // small ones we just use a multiplicative hash.
+  // For large values we use LowLevelHash or CityHash depending on the platform,
+  // for small ones we just use a multiplicative hash.
   uint64_t v;
   if (len > 16) {
     if (ABSL_PREDICT_FALSE(len > PiecewiseChunkSize())) {
diff --git a/absl/hash/internal/wyhash.cc b/absl/hash/internal/low_level_hash.cc
similarity index 84%
rename from absl/hash/internal/wyhash.cc
rename to absl/hash/internal/low_level_hash.cc
index 642bde4..856bbd9 100644
--- a/absl/hash/internal/wyhash.cc
+++ b/absl/hash/internal/low_level_hash.cc
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "absl/hash/internal/wyhash.h"
+#include "absl/hash/internal/low_level_hash.h"
 
 #include "absl/base/internal/unaligned_access.h"
 #include "absl/numeric/int128.h"
@@ -21,14 +21,14 @@
 ABSL_NAMESPACE_BEGIN
 namespace hash_internal {
 
-static uint64_t WyhashMix(uint64_t v0, uint64_t v1) {
+static uint64_t Mix(uint64_t v0, uint64_t v1) {
   absl::uint128 p = v0;
   p *= v1;
   return absl::Uint128Low64(p) ^ absl::Uint128High64(p);
 }
 
-uint64_t Wyhash(const void* data, size_t len, uint64_t seed,
-                const uint64_t salt[]) {
+uint64_t LowLevelHash(const void* data, size_t len, uint64_t seed,
+                      const uint64_t salt[]) {
   const uint8_t* ptr = static_cast<const uint8_t*>(data);
   uint64_t starting_length = static_cast<uint64_t>(len);
   uint64_t current_state = seed ^ salt[0];
@@ -49,12 +49,12 @@
       uint64_t g = absl::base_internal::UnalignedLoad64(ptr + 48);
       uint64_t h = absl::base_internal::UnalignedLoad64(ptr + 56);
 
-      uint64_t cs0 = WyhashMix(a ^ salt[1], b ^ current_state);
-      uint64_t cs1 = WyhashMix(c ^ salt[2], d ^ current_state);
+      uint64_t cs0 = Mix(a ^ salt[1], b ^ current_state);
+      uint64_t cs1 = Mix(c ^ salt[2], d ^ current_state);
       current_state = (cs0 ^ cs1);
 
-      uint64_t ds0 = WyhashMix(e ^ salt[3], f ^ duplicated_state);
-      uint64_t ds1 = WyhashMix(g ^ salt[4], h ^ duplicated_state);
+      uint64_t ds0 = Mix(e ^ salt[3], f ^ duplicated_state);
+      uint64_t ds1 = Mix(g ^ salt[4], h ^ duplicated_state);
       duplicated_state = (ds0 ^ ds1);
 
       ptr += 64;
@@ -70,7 +70,7 @@
     uint64_t a = absl::base_internal::UnalignedLoad64(ptr);
     uint64_t b = absl::base_internal::UnalignedLoad64(ptr + 8);
 
-    current_state = WyhashMix(a ^ salt[1], b ^ current_state);
+    current_state = Mix(a ^ salt[1], b ^ current_state);
 
     ptr += 16;
     len -= 16;
@@ -101,9 +101,9 @@
     b = 0;
   }
 
-  uint64_t w = WyhashMix(a ^ salt[1], b ^ current_state);
+  uint64_t w = Mix(a ^ salt[1], b ^ current_state);
   uint64_t z = salt[1] ^ starting_length;
-  return WyhashMix(w, z);
+  return Mix(w, z);
 }
 
 }  // namespace hash_internal
diff --git a/absl/hash/internal/wyhash.h b/absl/hash/internal/low_level_hash.h
similarity index 61%
rename from absl/hash/internal/wyhash.h
rename to absl/hash/internal/low_level_hash.h
index 2b534b4..439968a 100644
--- a/absl/hash/internal/wyhash.h
+++ b/absl/hash/internal/low_level_hash.h
@@ -12,16 +12,18 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 //
-// This file provides the Google-internal implementation of the Wyhash
-// algorithm.
+// This file provides the Google-internal implementation of LowLevelHash.
 //
-// Wyhash is a fast hash function for hash tables, the fastest we've currently
-// (late 2020) found that passes the SMHasher tests. The algorithm relies on
-// intrinsic 128-bit multiplication for speed. This is not meant to be secure -
-// just fast.
+// LowLevelHash is a fast hash function for hash tables, the fastest we've
+// currently (late 2020) found that passes the SMHasher tests. The algorithm
+// relies on intrinsic 128-bit multiplication for speed. This is not meant to be
+// secure - just fast.
+//
+// It is closely based on a version of wyhash, but does not maintain or
+// guarantee future compatibility with it.
 
-#ifndef ABSL_HASH_INTERNAL_WYHASH_H_
-#define ABSL_HASH_INTERNAL_WYHASH_H_
+#ifndef ABSL_HASH_INTERNAL_LOW_LEVEL_HASH_H_
+#define ABSL_HASH_INTERNAL_LOW_LEVEL_HASH_H_
 
 #include <stdint.h>
 #include <stdlib.h>
@@ -38,11 +40,11 @@
 // To allow all hashable types (including string_view and Span) to depend on
 // this algorithm, we keep the API low-level, with as few dependencies as
 // possible.
-uint64_t Wyhash(const void* data, size_t len, uint64_t seed,
-                const uint64_t salt[5]);
+uint64_t LowLevelHash(const void* data, size_t len, uint64_t seed,
+                      const uint64_t salt[5]);
 
 }  // namespace hash_internal
 ABSL_NAMESPACE_END
 }  // namespace absl
 
-#endif  // ABSL_HASH_INTERNAL_WYHASH_H_
+#endif  // ABSL_HASH_INTERNAL_LOW_LEVEL_HASH_H_
diff --git a/absl/hash/internal/wyhash_test.cc b/absl/hash/internal/low_level_hash_test.cc
similarity index 93%
rename from absl/hash/internal/wyhash_test.cc
rename to absl/hash/internal/low_level_hash_test.cc
index 9fb06d2..0ef5023 100644
--- a/absl/hash/internal/wyhash_test.cc
+++ b/absl/hash/internal/low_level_hash_test.cc
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "absl/hash/internal/wyhash.h"
+#include "absl/hash/internal/low_level_hash.h"
 
 #include "absl/strings/escaping.h"
 #include "gmock/gmock.h"
@@ -28,47 +28,47 @@
 // Note: We don't account for endianness, so the values here are only correct if
 // you're also running on a little endian platform.
 
-TEST(WyhashTest, EmptyString) {
+TEST(LowLevelHashTest, EmptyString) {
   const std::string s = "";
-  EXPECT_EQ(
-      absl::hash_internal::Wyhash(s.c_str(), s.length(), kCurrentSeed, kSalt),
-      4808886099364463827);
+  EXPECT_EQ(absl::hash_internal::LowLevelHash(s.c_str(), s.length(),
+                                              kCurrentSeed, kSalt),
+            4808886099364463827);
 }
 
-TEST(WyhashTest, Spaces) {
+TEST(LowLevelHashTest, Spaces) {
   const std::string s = "   ";
-  EXPECT_EQ(
-      absl::hash_internal::Wyhash(s.c_str(), s.length(), kCurrentSeed, kSalt),
-      1686201463024549249);
+  EXPECT_EQ(absl::hash_internal::LowLevelHash(s.c_str(), s.length(),
+                                              kCurrentSeed, kSalt),
+            1686201463024549249);
 }
 
-TEST(WyhashTest, RepeatingString) {
+TEST(LowLevelHashTest, RepeatingString) {
   const std::string s = "aaaa";
-  EXPECT_EQ(
-      absl::hash_internal::Wyhash(s.c_str(), s.length(), kCurrentSeed, kSalt),
-      6646112255271966632);
+  EXPECT_EQ(absl::hash_internal::LowLevelHash(s.c_str(), s.length(),
+                                              kCurrentSeed, kSalt),
+            6646112255271966632);
 }
 
-TEST(WyhashTest, HexString) {
+TEST(LowLevelHashTest, HexString) {
   const std::string small = "\x01\x02\x03";
   const std::string med = "\x01\x02\x03\x04";
 
-  EXPECT_EQ(absl::hash_internal::Wyhash(small.c_str(), small.length(),
-                                        kCurrentSeed, kSalt),
+  EXPECT_EQ(absl::hash_internal::LowLevelHash(small.c_str(), small.length(),
+                                              kCurrentSeed, kSalt),
             11989428023081740911ULL);
-  EXPECT_EQ(absl::hash_internal::Wyhash(med.c_str(), med.length(), kCurrentSeed,
-                                        kSalt),
+  EXPECT_EQ(absl::hash_internal::LowLevelHash(med.c_str(), med.length(),
+                                              kCurrentSeed, kSalt),
             9765997711188871556ULL);
 }
 
-TEST(WyhashTest, Words) {
+TEST(LowLevelHashTest, Words) {
   const std::string s = "third_party|wyhash|64";
-  EXPECT_EQ(
-      absl::hash_internal::Wyhash(s.c_str(), s.length(), kCurrentSeed, kSalt),
-      3702018632387611330);
+  EXPECT_EQ(absl::hash_internal::LowLevelHash(s.c_str(), s.length(),
+                                              kCurrentSeed, kSalt),
+            3702018632387611330);
 }
 
-TEST(WyhashTest, LongString) {
+TEST(LowLevelHashTest, LongString) {
   const std::string s =
       "AbCdEfGhIjKlMnOpQrStUvWxYz0123456789AbCdEfGhIjKlMnOpQrStUvWxYz"
       "0123456789AbCdEfGhIjKlMnOpQrStUvWxYz0123456789AbCdEfGhIjKlMnOp"
@@ -76,12 +76,12 @@
       "GhIjKlMnOpQrStUvWxYz0123456789AbCdEfGhIjKlMnOpQrStUvWxYz012345"
       "6789AbCdEfGhIjKlMnOpQrStUvWxYz0123456789";
 
-  EXPECT_EQ(
-      absl::hash_internal::Wyhash(s.c_str(), s.length(), kCurrentSeed, kSalt),
-      9245411362605796064ULL);
+  EXPECT_EQ(absl::hash_internal::LowLevelHash(s.c_str(), s.length(),
+                                              kCurrentSeed, kSalt),
+            9245411362605796064ULL);
 }
 
-TEST(WyhashTest, BigReference) {
+TEST(LowLevelHashTest, BigReference) {
   struct ExpectedResult {
     absl::string_view base64_data;
     uint64_t seed;
@@ -477,8 +477,8 @@
   for (const auto& expected_result : expected_results) {
     std::string str;
     ASSERT_TRUE(absl::Base64Unescape(expected_result.base64_data, &str));
-    EXPECT_EQ(absl::hash_internal::Wyhash(str.data(), str.size(),
-                                          expected_result.seed, kSalt),
+    EXPECT_EQ(absl::hash_internal::LowLevelHash(str.data(), str.size(),
+                                                expected_result.seed, kSalt),
               expected_result.hash);
   }
 }
diff --git a/absl/strings/substitute.h b/absl/strings/substitute.h
index c6da4dc..151c56f 100644
--- a/absl/strings/substitute.h
+++ b/absl/strings/substitute.h
@@ -361,43 +361,49 @@
 // This body of functions catches cases where the number of placeholders
 // doesn't match the number of data arguments.
 void SubstituteAndAppend(std::string* output, const char* format)
-    ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 0,
-                     "There were no substitution arguments "
-                     "but this format string has a $[0-9] in it");
+    ABSL_BAD_CALL_IF(
+        substitute_internal::PlaceholderBitmask(format) != 0,
+        "There were no substitution arguments "
+        "but this format string either has a $[0-9] in it or contains "
+        "an unescaped $ character (use $$ instead)");
 
 void SubstituteAndAppend(std::string* output, const char* format,
                          const substitute_internal::Arg& a0)
     ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 1,
                      "There was 1 substitution argument given, but "
-                     "this format string is either missing its $0, or "
-                     "contains one of $1-$9");
+                     "this format string is missing its $0, contains "
+                     "one of $1-$9, or contains an unescaped $ character (use "
+                     "$$ instead)");
 
 void SubstituteAndAppend(std::string* output, const char* format,
                          const substitute_internal::Arg& a0,
                          const substitute_internal::Arg& a1)
-    ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 3,
-                     "There were 2 substitution arguments given, but "
-                     "this format string is either missing its $0/$1, or "
-                     "contains one of $2-$9");
+    ABSL_BAD_CALL_IF(
+        substitute_internal::PlaceholderBitmask(format) != 3,
+        "There were 2 substitution arguments given, but this format string is "
+        "missing its $0/$1, contains one of $2-$9, or contains an "
+        "unescaped $ character (use $$ instead)");
 
 void SubstituteAndAppend(std::string* output, const char* format,
                          const substitute_internal::Arg& a0,
                          const substitute_internal::Arg& a1,
                          const substitute_internal::Arg& a2)
-    ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 7,
-                     "There were 3 substitution arguments given, but "
-                     "this format string is either missing its $0/$1/$2, or "
-                     "contains one of $3-$9");
+    ABSL_BAD_CALL_IF(
+        substitute_internal::PlaceholderBitmask(format) != 7,
+        "There were 3 substitution arguments given, but "
+        "this format string is missing its $0/$1/$2, contains one of "
+        "$3-$9, or contains an unescaped $ character (use $$ instead)");
 
 void SubstituteAndAppend(std::string* output, const char* format,
                          const substitute_internal::Arg& a0,
                          const substitute_internal::Arg& a1,
                          const substitute_internal::Arg& a2,
                          const substitute_internal::Arg& a3)
-    ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 15,
-                     "There were 4 substitution arguments given, but "
-                     "this format string is either missing its $0-$3, or "
-                     "contains one of $4-$9");
+    ABSL_BAD_CALL_IF(
+        substitute_internal::PlaceholderBitmask(format) != 15,
+        "There were 4 substitution arguments given, but "
+        "this format string is missing its $0-$3, contains one of "
+        "$4-$9, or contains an unescaped $ character (use $$ instead)");
 
 void SubstituteAndAppend(std::string* output, const char* format,
                          const substitute_internal::Arg& a0,
@@ -405,10 +411,11 @@
                          const substitute_internal::Arg& a2,
                          const substitute_internal::Arg& a3,
                          const substitute_internal::Arg& a4)
-    ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 31,
-                     "There were 5 substitution arguments given, but "
-                     "this format string is either missing its $0-$4, or "
-                     "contains one of $5-$9");
+    ABSL_BAD_CALL_IF(
+        substitute_internal::PlaceholderBitmask(format) != 31,
+        "There were 5 substitution arguments given, but "
+        "this format string is missing its $0-$4, contains one of "
+        "$5-$9, or contains an unescaped $ character (use $$ instead)");
 
 void SubstituteAndAppend(std::string* output, const char* format,
                          const substitute_internal::Arg& a0,
@@ -417,20 +424,22 @@
                          const substitute_internal::Arg& a3,
                          const substitute_internal::Arg& a4,
                          const substitute_internal::Arg& a5)
-    ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 63,
-                     "There were 6 substitution arguments given, but "
-                     "this format string is either missing its $0-$5, or "
-                     "contains one of $6-$9");
+    ABSL_BAD_CALL_IF(
+        substitute_internal::PlaceholderBitmask(format) != 63,
+        "There were 6 substitution arguments given, but "
+        "this format string is missing its $0-$5, contains one of "
+        "$6-$9, or contains an unescaped $ character (use $$ instead)");
 
 void SubstituteAndAppend(
     std::string* output, const char* format, const substitute_internal::Arg& a0,
     const substitute_internal::Arg& a1, const substitute_internal::Arg& a2,
     const substitute_internal::Arg& a3, const substitute_internal::Arg& a4,
     const substitute_internal::Arg& a5, const substitute_internal::Arg& a6)
-    ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 127,
-                     "There were 7 substitution arguments given, but "
-                     "this format string is either missing its $0-$6, or "
-                     "contains one of $7-$9");
+    ABSL_BAD_CALL_IF(
+        substitute_internal::PlaceholderBitmask(format) != 127,
+        "There were 7 substitution arguments given, but "
+        "this format string is missing its $0-$6, contains one of "
+        "$7-$9, or contains an unescaped $ character (use $$ instead)");
 
 void SubstituteAndAppend(
     std::string* output, const char* format, const substitute_internal::Arg& a0,
@@ -438,10 +447,11 @@
     const substitute_internal::Arg& a3, const substitute_internal::Arg& a4,
     const substitute_internal::Arg& a5, const substitute_internal::Arg& a6,
     const substitute_internal::Arg& a7)
-    ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 255,
-                     "There were 8 substitution arguments given, but "
-                     "this format string is either missing its $0-$7, or "
-                     "contains one of $8-$9");
+    ABSL_BAD_CALL_IF(
+        substitute_internal::PlaceholderBitmask(format) != 255,
+        "There were 8 substitution arguments given, but "
+        "this format string is missing its $0-$7, contains one of "
+        "$8-$9, or contains an unescaped $ character (use $$ instead)");
 
 void SubstituteAndAppend(
     std::string* output, const char* format, const substitute_internal::Arg& a0,
@@ -452,7 +462,8 @@
     ABSL_BAD_CALL_IF(
         substitute_internal::PlaceholderBitmask(format) != 511,
         "There were 9 substitution arguments given, but "
-        "this format string is either missing its $0-$8, or contains a $9");
+        "this format string is missing its $0-$8, contains a $9, or "
+        "contains an unescaped $ character (use $$ instead)");
 
 void SubstituteAndAppend(
     std::string* output, const char* format, const substitute_internal::Arg& a0,
@@ -461,9 +472,11 @@
     const substitute_internal::Arg& a5, const substitute_internal::Arg& a6,
     const substitute_internal::Arg& a7, const substitute_internal::Arg& a8,
     const substitute_internal::Arg& a9)
-    ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 1023,
-                     "There were 10 substitution arguments given, but this "
-                     "format string doesn't contain all of $0 through $9");
+    ABSL_BAD_CALL_IF(
+        substitute_internal::PlaceholderBitmask(format) != 1023,
+        "There were 10 substitution arguments given, but this "
+        "format string either doesn't contain all of $0 through $9 or "
+        "contains an unescaped $ character (use $$ instead)");
 #endif  // ABSL_BAD_CALL_IF
 
 // Substitute()
@@ -589,47 +602,53 @@
 std::string Substitute(const char* format)
     ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 0,
                      "There were no substitution arguments "
-                     "but this format string has a $[0-9] in it");
+                     "but this format string either has a $[0-9] in it or "
+                     "contains an unescaped $ character (use $$ instead)");
 
 std::string Substitute(const char* format, const substitute_internal::Arg& a0)
-    ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 1,
-                     "There was 1 substitution argument given, but "
-                     "this format string is either missing its $0, or "
-                     "contains one of $1-$9");
+    ABSL_BAD_CALL_IF(
+        substitute_internal::PlaceholderBitmask(format) != 1,
+        "There was 1 substitution argument given, but "
+        "this format string is missing its $0, contains one of $1-$9, "
+        "or contains an unescaped $ character (use $$ instead)");
 
 std::string Substitute(const char* format, const substitute_internal::Arg& a0,
                        const substitute_internal::Arg& a1)
-    ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 3,
-                     "There were 2 substitution arguments given, but "
-                     "this format string is either missing its $0/$1, or "
-                     "contains one of $2-$9");
+    ABSL_BAD_CALL_IF(
+        substitute_internal::PlaceholderBitmask(format) != 3,
+        "There were 2 substitution arguments given, but "
+        "this format string is missing its $0/$1, contains one of "
+        "$2-$9, or contains an unescaped $ character (use $$ instead)");
 
 std::string Substitute(const char* format, const substitute_internal::Arg& a0,
                        const substitute_internal::Arg& a1,
                        const substitute_internal::Arg& a2)
-    ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 7,
-                     "There were 3 substitution arguments given, but "
-                     "this format string is either missing its $0/$1/$2, or "
-                     "contains one of $3-$9");
+    ABSL_BAD_CALL_IF(
+        substitute_internal::PlaceholderBitmask(format) != 7,
+        "There were 3 substitution arguments given, but "
+        "this format string is missing its $0/$1/$2, contains one of "
+        "$3-$9, or contains an unescaped $ character (use $$ instead)");
 
 std::string Substitute(const char* format, const substitute_internal::Arg& a0,
                        const substitute_internal::Arg& a1,
                        const substitute_internal::Arg& a2,
                        const substitute_internal::Arg& a3)
-    ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 15,
-                     "There were 4 substitution arguments given, but "
-                     "this format string is either missing its $0-$3, or "
-                     "contains one of $4-$9");
+    ABSL_BAD_CALL_IF(
+        substitute_internal::PlaceholderBitmask(format) != 15,
+        "There were 4 substitution arguments given, but "
+        "this format string is missing its $0-$3, contains one of "
+        "$4-$9, or contains an unescaped $ character (use $$ instead)");
 
 std::string Substitute(const char* format, const substitute_internal::Arg& a0,
                        const substitute_internal::Arg& a1,
                        const substitute_internal::Arg& a2,
                        const substitute_internal::Arg& a3,
                        const substitute_internal::Arg& a4)
-    ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 31,
-                     "There were 5 substitution arguments given, but "
-                     "this format string is either missing its $0-$4, or "
-                     "contains one of $5-$9");
+    ABSL_BAD_CALL_IF(
+        substitute_internal::PlaceholderBitmask(format) != 31,
+        "There were 5 substitution arguments given, but "
+        "this format string is missing its $0-$4, contains one of "
+        "$5-$9, or contains an unescaped $ character (use $$ instead)");
 
 std::string Substitute(const char* format, const substitute_internal::Arg& a0,
                        const substitute_internal::Arg& a1,
@@ -637,10 +656,11 @@
                        const substitute_internal::Arg& a3,
                        const substitute_internal::Arg& a4,
                        const substitute_internal::Arg& a5)
-    ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 63,
-                     "There were 6 substitution arguments given, but "
-                     "this format string is either missing its $0-$5, or "
-                     "contains one of $6-$9");
+    ABSL_BAD_CALL_IF(
+        substitute_internal::PlaceholderBitmask(format) != 63,
+        "There were 6 substitution arguments given, but "
+        "this format string is missing its $0-$5, contains one of "
+        "$6-$9, or contains an unescaped $ character (use $$ instead)");
 
 std::string Substitute(const char* format, const substitute_internal::Arg& a0,
                        const substitute_internal::Arg& a1,
@@ -649,10 +669,11 @@
                        const substitute_internal::Arg& a4,
                        const substitute_internal::Arg& a5,
                        const substitute_internal::Arg& a6)
-    ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 127,
-                     "There were 7 substitution arguments given, but "
-                     "this format string is either missing its $0-$6, or "
-                     "contains one of $7-$9");
+    ABSL_BAD_CALL_IF(
+        substitute_internal::PlaceholderBitmask(format) != 127,
+        "There were 7 substitution arguments given, but "
+        "this format string is missing its $0-$6, contains one of "
+        "$7-$9, or contains an unescaped $ character (use $$ instead)");
 
 std::string Substitute(const char* format, const substitute_internal::Arg& a0,
                        const substitute_internal::Arg& a1,
@@ -662,10 +683,11 @@
                        const substitute_internal::Arg& a5,
                        const substitute_internal::Arg& a6,
                        const substitute_internal::Arg& a7)
-    ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 255,
-                     "There were 8 substitution arguments given, but "
-                     "this format string is either missing its $0-$7, or "
-                     "contains one of $8-$9");
+    ABSL_BAD_CALL_IF(
+        substitute_internal::PlaceholderBitmask(format) != 255,
+        "There were 8 substitution arguments given, but "
+        "this format string is missing its $0-$7, contains one of "
+        "$8-$9, or contains an unescaped $ character (use $$ instead)");
 
 std::string Substitute(
     const char* format, const substitute_internal::Arg& a0,
@@ -676,7 +698,8 @@
     ABSL_BAD_CALL_IF(
         substitute_internal::PlaceholderBitmask(format) != 511,
         "There were 9 substitution arguments given, but "
-        "this format string is either missing its $0-$8, or contains a $9");
+        "this format string is missing its $0-$8, contains a $9, or "
+        "contains an unescaped $ character (use $$ instead)");
 
 std::string Substitute(
     const char* format, const substitute_internal::Arg& a0,
@@ -685,9 +708,11 @@
     const substitute_internal::Arg& a5, const substitute_internal::Arg& a6,
     const substitute_internal::Arg& a7, const substitute_internal::Arg& a8,
     const substitute_internal::Arg& a9)
-    ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 1023,
-                     "There were 10 substitution arguments given, but this "
-                     "format string doesn't contain all of $0 through $9");
+    ABSL_BAD_CALL_IF(
+        substitute_internal::PlaceholderBitmask(format) != 1023,
+        "There were 10 substitution arguments given, but this "
+        "format string either doesn't contain all of $0 through $9 or "
+        "contains an unescaped $ character (use $$ instead)");
 #endif  // ABSL_BAD_CALL_IF
 
 ABSL_NAMESPACE_END
diff --git a/absl/time/internal/cctz/BUILD.bazel b/absl/time/internal/cctz/BUILD.bazel
index 45a9529..f549af6 100644
--- a/absl/time/internal/cctz/BUILD.bazel
+++ b/absl/time/internal/cctz/BUILD.bazel
@@ -26,14 +26,14 @@
 config_setting(
     name = "osx",
     constraint_values = [
-        "@bazel_tools//platforms:osx",
+        "@platforms//os:osx",
     ],
 )
 
 config_setting(
     name = "ios",
     constraint_values = [
-        "@bazel_tools//platforms:ios",
+        "@platforms//os:ios",
     ],
 )
 
diff --git a/absl/types/bad_optional_access.h b/absl/types/bad_optional_access.h
index a500286..049e72a 100644
--- a/absl/types/bad_optional_access.h
+++ b/absl/types/bad_optional_access.h
@@ -67,7 +67,7 @@
 namespace optional_internal {
 
 // throw delegator
-[[noreturn]] void throw_bad_optional_access();
+[[noreturn]] ABSL_DLL void throw_bad_optional_access();
 
 }  // namespace optional_internal
 ABSL_NAMESPACE_END
diff --git a/absl/types/bad_variant_access.h b/absl/types/bad_variant_access.h
index 095969f..8ab215e 100644
--- a/absl/types/bad_variant_access.h
+++ b/absl/types/bad_variant_access.h
@@ -70,8 +70,8 @@
 
 namespace variant_internal {
 
-[[noreturn]] void ThrowBadVariantAccess();
-[[noreturn]] void Rethrow();
+[[noreturn]] ABSL_DLL void ThrowBadVariantAccess();
+[[noreturn]] ABSL_DLL void Rethrow();
 
 }  // namespace variant_internal
 ABSL_NAMESPACE_END
diff --git a/absl/types/span.h b/absl/types/span.h
index 41db342..6272bb7 100644
--- a/absl/types/span.h
+++ b/absl/types/span.h
@@ -40,7 +40,6 @@
 //    * `absl::Span` has compiler-provided move and copy constructors and
 //      assignment. This is due to them being specified as `constexpr`, but that
 //      implies const in C++11.
-//    * `absl::Span` has no `element_type` typedef
 //    * A read-only `absl::Span<const T>` can be implicitly constructed from an
 //      initializer list.
 //    * `absl::Span` has no `bytes()`, `size_bytes()`, `as_bytes()`, or
@@ -170,6 +169,7 @@
       typename std::enable_if<!std::is_const<T>::value, U>::type;
 
  public:
+  using element_type = T;
   using value_type = absl::remove_cv_t<T>;
   using pointer = T*;
   using const_pointer = const T*;
diff --git a/absl/types/span_test.cc b/absl/types/span_test.cc
index 2584339..13264aa 100644
--- a/absl/types/span_test.cc
+++ b/absl/types/span_test.cc
@@ -661,6 +661,8 @@
   CheckType<absl::Span<int>::const_reverse_iterator>(slice.crend());
   testing::StaticAssertTypeEq<int, absl::Span<int>::value_type>();
   testing::StaticAssertTypeEq<int, absl::Span<const int>::value_type>();
+  testing::StaticAssertTypeEq<int, absl::Span<int>::element_type>();
+  testing::StaticAssertTypeEq<const int, absl::Span<const int>::element_type>();
   testing::StaticAssertTypeEq<int*, absl::Span<int>::pointer>();
   testing::StaticAssertTypeEq<const int*, absl::Span<const int>::pointer>();
   testing::StaticAssertTypeEq<int&, absl::Span<int>::reference>();
diff --git a/symbols_arm64_dbg.def b/symbols_arm64_dbg.def
index 6755815..16ef24d 100644
--- a/symbols_arm64_dbg.def
+++ b/symbols_arm64_dbg.def
@@ -2144,6 +2144,8 @@
     ?LogSeverityName@absl@@YAPEBDW4LogSeverity@1@@Z
     ?LossyAdd@CordzUpdateTracker@cord_internal@absl@@QEAAXAEBV123@@Z
     ?LossyAdd@CordzUpdateTracker@cord_internal@absl@@QEAAXW4MethodIdentifier@123@_J@Z
+    ?LowLevelHash@hash_internal@absl@@YA_KPEBX_K1QEB_K@Z
+    ?LowLevelHashImpl@MixingHashState@hash_internal@absl@@CA_KPEBE_K@Z
     ?MakeConcat@CordForest@absl@@AEAAPEAUCordRep@cord_internal@2@PEAU342@0@Z
     ?MakeDuration@time_internal@absl@@YA?AVDuration@2@_J0@Z
     ?MakeDuration@time_internal@absl@@YA?AVDuration@2@_JI@Z
@@ -2600,8 +2602,6 @@
     ?Write@BufferRawSink@str_format_internal@absl@@QEAAXVstring_view@3@@Z
     ?Write@FILERawSink@str_format_internal@absl@@QEAAXVstring_view@3@@Z
     ?Write@FormatRawSinkImpl@str_format_internal@absl@@QEAAXVstring_view@3@@Z
-    ?Wyhash@hash_internal@absl@@YA_KPEBX_K1QEB_K@Z
-    ?WyhashImpl@MixingHashState@hash_internal@absl@@CA_KPEBE_K@Z
     ?ZeroDuration@absl@@YA?AVDuration@1@XZ
     ?__add_back_capacity@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAXXZ
     ?__addr@?$__temp_value@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
diff --git a/symbols_arm64_rel.def b/symbols_arm64_rel.def
index e0b68df..b225999 100644
--- a/symbols_arm64_rel.def
+++ b/symbols_arm64_rel.def
@@ -528,6 +528,8 @@
     ?LockWhen@Mutex@absl@@QEAAXAEBVCondition@2@@Z
     ?LockWhenWithDeadline@Mutex@absl@@QEAA_NAEBVCondition@2@VTime@2@@Z
     ?LockWhenWithTimeout@Mutex@absl@@QEAA_NAEBVCondition@2@VDuration@2@@Z
+    ?LowLevelHash@hash_internal@absl@@YA_KPEBX_K1QEB_K@Z
+    ?LowLevelHashImpl@MixingHashState@hash_internal@absl@@CA_KPEBE_K@Z
     ?MakeConcat@CordForest@absl@@AEAAPEAUCordRep@cord_internal@2@PEAU342@0@Z
     ?MakeTime@TimeZoneInfo@cctz@time_internal@absl@@UEBA?AUcivil_lookup@time_zone@234@AEBV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@234@@Z
     ?MakeTime@TimeZoneLibC@cctz@time_internal@absl@@UEBA?AUcivil_lookup@time_zone@234@AEBV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@234@@Z
@@ -810,8 +812,6 @@
     ?WebSafeBase64Unescape@absl@@YA_NVstring_view@1@PEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
     ?Write@BufferRawSink@str_format_internal@absl@@QEAAXVstring_view@3@@Z
     ?Write@FILERawSink@str_format_internal@absl@@QEAAXVstring_view@3@@Z
-    ?Wyhash@hash_internal@absl@@YA_KPEBX_K1QEB_K@Z
-    ?WyhashImpl@MixingHashState@hash_internal@absl@@CA_KPEBE_K@Z
     ?__add_back_capacity@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAXXZ
     ?__append@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAX_K@Z
     ?__append@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAX_K@Z
diff --git a/symbols_x64_dbg.def b/symbols_x64_dbg.def
index fa8d8f0..1342821 100644
--- a/symbols_x64_dbg.def
+++ b/symbols_x64_dbg.def
@@ -2145,6 +2145,8 @@
     ?LogSeverityName@absl@@YAPEBDW4LogSeverity@1@@Z
     ?LossyAdd@CordzUpdateTracker@cord_internal@absl@@QEAAXAEBV123@@Z
     ?LossyAdd@CordzUpdateTracker@cord_internal@absl@@QEAAXW4MethodIdentifier@123@_J@Z
+    ?LowLevelHash@hash_internal@absl@@YA_KPEBX_K1QEB_K@Z
+    ?LowLevelHashImpl@MixingHashState@hash_internal@absl@@CA_KPEBE_K@Z
     ?MakeConcat@CordForest@absl@@AEAAPEAUCordRep@cord_internal@2@PEAU342@0@Z
     ?MakeDuration@time_internal@absl@@YA?AVDuration@2@_J0@Z
     ?MakeDuration@time_internal@absl@@YA?AVDuration@2@_JI@Z
@@ -2598,8 +2600,6 @@
     ?Write@BufferRawSink@str_format_internal@absl@@QEAAXVstring_view@3@@Z
     ?Write@FILERawSink@str_format_internal@absl@@QEAAXVstring_view@3@@Z
     ?Write@FormatRawSinkImpl@str_format_internal@absl@@QEAAXVstring_view@3@@Z
-    ?Wyhash@hash_internal@absl@@YA_KPEBX_K1QEB_K@Z
-    ?WyhashImpl@MixingHashState@hash_internal@absl@@CA_KPEBE_K@Z
     ?ZeroDuration@absl@@YA?AVDuration@1@XZ
     ?__add_back_capacity@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAXXZ
     ?__addr@?$__temp_value@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
diff --git a/symbols_x64_rel.def b/symbols_x64_rel.def
index 35bcb17..52adc37 100644
--- a/symbols_x64_rel.def
+++ b/symbols_x64_rel.def
@@ -532,6 +532,8 @@
     ?LockWhen@Mutex@absl@@QEAAXAEBVCondition@2@@Z
     ?LockWhenWithDeadline@Mutex@absl@@QEAA_NAEBVCondition@2@VTime@2@@Z
     ?LockWhenWithTimeout@Mutex@absl@@QEAA_NAEBVCondition@2@VDuration@2@@Z
+    ?LowLevelHash@hash_internal@absl@@YA_KPEBX_K1QEB_K@Z
+    ?LowLevelHashImpl@MixingHashState@hash_internal@absl@@CA_KPEBE_K@Z
     ?MakeConcat@CordForest@absl@@AEAAPEAUCordRep@cord_internal@2@PEAU342@0@Z
     ?MakeNs@KernelTimeout@synchronization_internal@absl@@CA_JVTime@3@@Z
     ?MakeTime@TimeZoneInfo@cctz@time_internal@absl@@UEBA?AUcivil_lookup@time_zone@234@AEBV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@234@@Z
@@ -815,8 +817,6 @@
     ?WebSafeBase64Unescape@absl@@YA_NVstring_view@1@PEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
     ?Write@BufferRawSink@str_format_internal@absl@@QEAAXVstring_view@3@@Z
     ?Write@FILERawSink@str_format_internal@absl@@QEAAXVstring_view@3@@Z
-    ?Wyhash@hash_internal@absl@@YA_KPEBX_K1QEB_K@Z
-    ?WyhashImpl@MixingHashState@hash_internal@absl@@CA_KPEBE_K@Z
     ?__add_back_capacity@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAXXZ
     ?__append@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAX_K@Z
     ?__append@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAX_K@Z
diff --git a/symbols_x64_rel_asan.def b/symbols_x64_rel_asan.def
index 44d4b15..a0a34b2 100644
--- a/symbols_x64_rel_asan.def
+++ b/symbols_x64_rel_asan.def
@@ -545,6 +545,8 @@
     ?LockWhen@Mutex@absl@@QEAAXAEBVCondition@2@@Z
     ?LockWhenWithDeadline@Mutex@absl@@QEAA_NAEBVCondition@2@VTime@2@@Z
     ?LockWhenWithTimeout@Mutex@absl@@QEAA_NAEBVCondition@2@VDuration@2@@Z
+    ?LowLevelHash@hash_internal@absl@@YA_KPEBX_K1QEB_K@Z
+    ?LowLevelHashImpl@MixingHashState@hash_internal@absl@@CA_KPEBE_K@Z
     ?MakeConcat@CordForest@absl@@AEAAPEAUCordRep@cord_internal@2@PEAU342@0@Z
     ?MakeNs@KernelTimeout@synchronization_internal@absl@@CA_JVTime@3@@Z
     ?MakeTime@TimeZoneInfo@cctz@time_internal@absl@@UEBA?AUcivil_lookup@time_zone@234@AEBV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@234@@Z
@@ -828,8 +830,6 @@
     ?WebSafeBase64Unescape@absl@@YA_NVstring_view@1@PEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
     ?Write@BufferRawSink@str_format_internal@absl@@QEAAXVstring_view@3@@Z
     ?Write@FILERawSink@str_format_internal@absl@@QEAAXVstring_view@3@@Z
-    ?Wyhash@hash_internal@absl@@YA_KPEBX_K1QEB_K@Z
-    ?WyhashImpl@MixingHashState@hash_internal@absl@@CA_KPEBE_K@Z
     ?__add_back_capacity@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@AEAAXXZ
     ?__annotate_delete@?$vector@PEAUCordRep@cord_internal@absl@@V?$allocator@PEAUCordRep@cord_internal@absl@@@__1@std@@@__1@std@@AEBAXXZ
     ?__annotate_delete@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__1@std@@@__1@std@@AEBAXXZ
diff --git a/symbols_x86_dbg.def b/symbols_x86_dbg.def
index a01d397..f778175 100644
--- a/symbols_x86_dbg.def
+++ b/symbols_x86_dbg.def
@@ -2139,6 +2139,8 @@
     ?LogSeverityName@absl@@YAPBDW4LogSeverity@1@@Z
     ?LossyAdd@CordzUpdateTracker@cord_internal@absl@@QAEXABV123@@Z
     ?LossyAdd@CordzUpdateTracker@cord_internal@absl@@QAEXW4MethodIdentifier@123@_J@Z
+    ?LowLevelHash@hash_internal@absl@@YA_KPBXI_KQB_K@Z
+    ?LowLevelHashImpl@MixingHashState@hash_internal@absl@@CA_KPBEI@Z
     ?MakeConcat@CordForest@absl@@AAEPAUCordRep@cord_internal@2@PAU342@0@Z
     ?MakeDuration@time_internal@absl@@YA?AVDuration@2@_J0@Z
     ?MakeDuration@time_internal@absl@@YA?AVDuration@2@_JI@Z
@@ -2592,8 +2594,6 @@
     ?Write@BufferRawSink@str_format_internal@absl@@QAEXVstring_view@3@@Z
     ?Write@FILERawSink@str_format_internal@absl@@QAEXVstring_view@3@@Z
     ?Write@FormatRawSinkImpl@str_format_internal@absl@@QAEXVstring_view@3@@Z
-    ?Wyhash@hash_internal@absl@@YA_KPBXI_KQB_K@Z
-    ?WyhashImpl@MixingHashState@hash_internal@absl@@CA_KPBEI@Z
     ?ZeroDuration@absl@@YA?AVDuration@1@XZ
     ?__add_back_capacity@?$deque@PBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@AAEXXZ
     ?__addr@?$__temp_value@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEPAUTransition@cctz@time_internal@absl@@XZ
diff --git a/symbols_x86_rel.def b/symbols_x86_rel.def
index 4cadd32..c3d765b 100644
--- a/symbols_x86_rel.def
+++ b/symbols_x86_rel.def
@@ -530,6 +530,8 @@
     ?LockWhen@Mutex@absl@@QAEXABVCondition@2@@Z
     ?LockWhenWithDeadline@Mutex@absl@@QAE_NABVCondition@2@VTime@2@@Z
     ?LockWhenWithTimeout@Mutex@absl@@QAE_NABVCondition@2@VDuration@2@@Z
+    ?LowLevelHash@hash_internal@absl@@YA_KPBXI_KQB_K@Z
+    ?LowLevelHashImpl@MixingHashState@hash_internal@absl@@CA_KPBEI@Z
     ?MakeConcat@CordForest@absl@@AAEPAUCordRep@cord_internal@2@PAU342@0@Z
     ?MakeTime@TimeZoneInfo@cctz@time_internal@absl@@UBE?AUcivil_lookup@time_zone@234@ABV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@234@@Z
     ?MakeTime@TimeZoneLibC@cctz@time_internal@absl@@UBE?AUcivil_lookup@time_zone@234@ABV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@234@@Z
@@ -812,8 +814,6 @@
     ?WebSafeBase64Unescape@absl@@YA_NVstring_view@1@PAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@Z
     ?Write@BufferRawSink@str_format_internal@absl@@QAEXVstring_view@3@@Z
     ?Write@FILERawSink@str_format_internal@absl@@QAEXVstring_view@3@@Z
-    ?Wyhash@hash_internal@absl@@YA_KPBXI_KQB_K@Z
-    ?WyhashImpl@MixingHashState@hash_internal@absl@@CA_KPBEI@Z
     ?__add_back_capacity@?$deque@PBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@AAEXXZ
     ?__append@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@AAEXI@Z
     ?__append@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__1@std@@@__1@std@@AAEXI@Z