about summary refs log tree commit diff
path: root/absl
diff options
context:
space:
mode:
Diffstat (limited to 'absl')
-rw-r--r--absl/base/BUILD.bazel10
-rw-r--r--absl/base/attributes.h3
-rw-r--r--absl/base/internal/unaligned_access.h84
-rw-r--r--absl/container/BUILD.bazel4
-rw-r--r--absl/container/CMakeLists.txt1
-rw-r--r--absl/container/fixed_array.h7
-rw-r--r--absl/container/fixed_array_test.cc2
-rw-r--r--absl/container/flat_hash_map.h12
-rw-r--r--absl/container/flat_hash_set.h4
-rw-r--r--absl/container/inlined_vector.h6
-rw-r--r--absl/container/inlined_vector_test.cc2
-rw-r--r--absl/container/internal/hash_function_defaults.h5
-rw-r--r--absl/container/internal/raw_hash_set.h17
-rw-r--r--absl/container/internal/raw_hash_set_test.cc4
-rw-r--r--absl/container/node_hash_map.h12
-rw-r--r--absl/container/node_hash_set.h4
-rw-r--r--absl/copts.bzl7
-rw-r--r--absl/hash/internal/city.cc25
-rw-r--r--absl/numeric/BUILD.bazel1
-rw-r--r--absl/numeric/int128.h6
-rw-r--r--absl/numeric/int128_test.cc1
-rw-r--r--absl/synchronization/BUILD.bazel7
-rw-r--r--absl/time/time.h15
-rw-r--r--absl/types/BUILD.bazel2
-rw-r--r--absl/types/span.h7
-rw-r--r--absl/types/span_test.cc1
26 files changed, 176 insertions, 73 deletions
diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel
index 83d48f6b20a0..f7d810135b8c 100644
--- a/absl/base/BUILD.bazel
+++ b/absl/base/BUILD.bazel
@@ -305,6 +305,7 @@ cc_test(
     size = "medium",
     srcs = ["spinlock_test_common.cc"],
     copts = ABSL_TEST_COPTS,
+    tags = ["no_test_wasm"],
     deps = [
         ":base",
         ":core_headers",
@@ -343,6 +344,9 @@ cc_test(
     name = "config_test",
     srcs = ["config_test.cc"],
     copts = ABSL_TEST_COPTS,
+    tags = [
+        "no_test_wasm",
+    ],
     deps = [
         ":config",
         "//absl/synchronization:thread_pool",
@@ -354,6 +358,9 @@ cc_test(
     name = "call_once_test",
     srcs = ["call_once_test.cc"],
     copts = ABSL_TEST_COPTS,
+    tags = [
+        "no_test_wasm",
+    ],
     deps = [
         ":base",
         ":core_headers",
@@ -407,6 +414,9 @@ cc_test(
         "//absl:windows": [],
         "//conditions:default": ["-pthread"],
     }),
+    tags = [
+        "no_test_wasm",
+    ],
     deps = [
         ":base",
         ":core_headers",
diff --git a/absl/base/attributes.h b/absl/base/attributes.h
index cc933bbaaee8..e8500224443b 100644
--- a/absl/base/attributes.h
+++ b/absl/base/attributes.h
@@ -514,8 +514,7 @@
 
 // ABSL_ATTRIBUTE_UNUSED
 //
-// Prevents the compiler from complaining about or optimizing away variables
-// that appear unused.
+// Prevents the compiler from complaining about variables that appear unused.
 #if ABSL_HAVE_ATTRIBUTE(unused) || (defined(__GNUC__) && !defined(__clang__))
 #undef ABSL_ATTRIBUTE_UNUSED
 #define ABSL_ATTRIBUTE_UNUSED __attribute__((__unused__))
diff --git a/absl/base/internal/unaligned_access.h b/absl/base/internal/unaligned_access.h
index 5c7517abd71a..f9df3b7848c4 100644
--- a/absl/base/internal/unaligned_access.h
+++ b/absl/base/internal/unaligned_access.h
@@ -65,6 +65,7 @@ void __sanitizer_unaligned_store64(void *p, uint64_t v);
 }  // extern "C"
 
 namespace absl {
+namespace base_internal {
 
 inline uint16_t UnalignedLoad16(const void *p) {
   return __sanitizer_unaligned_load16(p);
@@ -90,22 +91,27 @@ inline void UnalignedStore64(void *p, uint64_t v) {
   __sanitizer_unaligned_store64(p, v);
 }
 
+}  // namespace base_internal
 }  // namespace absl
 
-#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) (absl::UnalignedLoad16(_p))
-#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) (absl::UnalignedLoad32(_p))
-#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) (absl::UnalignedLoad64(_p))
+#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \
+  (absl::base_internal::UnalignedLoad16(_p))
+#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) \
+  (absl::base_internal::UnalignedLoad32(_p))
+#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) \
+  (absl::base_internal::UnalignedLoad64(_p))
 
 #define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val) \
-  (absl::UnalignedStore16(_p, _val))
+  (absl::base_internal::UnalignedStore16(_p, _val))
 #define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \
-  (absl::UnalignedStore32(_p, _val))
+  (absl::base_internal::UnalignedStore32(_p, _val))
 #define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \
-  (absl::UnalignedStore64(_p, _val))
+  (absl::base_internal::UnalignedStore64(_p, _val))
 
 #elif defined(UNDEFINED_BEHAVIOR_SANITIZER)
 
 namespace absl {
+namespace base_internal {
 
 inline uint16_t UnalignedLoad16(const void *p) {
   uint16_t t;
@@ -131,18 +137,22 @@ inline void UnalignedStore32(void *p, uint32_t v) { memcpy(p, &v, sizeof v); }
 
 inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); }
 
+}  // namespace base_internal
 }  // namespace absl
 
-#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) (absl::UnalignedLoad16(_p))
-#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) (absl::UnalignedLoad32(_p))
-#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) (absl::UnalignedLoad64(_p))
+#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \
+  (absl::base_internal::UnalignedLoad16(_p))
+#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) \
+  (absl::base_internal::UnalignedLoad32(_p))
+#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) \
+  (absl::base_internal::UnalignedLoad64(_p))
 
 #define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val) \
-  (absl::UnalignedStore16(_p, _val))
+  (absl::base_internal::UnalignedStore16(_p, _val))
 #define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \
-  (absl::UnalignedStore32(_p, _val))
+  (absl::base_internal::UnalignedStore32(_p, _val))
 #define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \
-  (absl::UnalignedStore64(_p, _val))
+  (absl::base_internal::UnalignedStore64(_p, _val))
 
 #elif defined(__x86_64__) || defined(_M_X64) || defined(__i386) || \
     defined(_M_IX86) || defined(__ppc__) || defined(__PPC__) ||    \
@@ -199,7 +209,7 @@ inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); }
 // so we do that.
 
 namespace absl {
-namespace internal {
+namespace base_internal {
 
 struct Unaligned16Struct {
   uint16_t value;
@@ -211,22 +221,25 @@ struct Unaligned32Struct {
   uint8_t dummy;  // To make the size non-power-of-two.
 } ABSL_ATTRIBUTE_PACKED;
 
-}  // namespace internal
+}  // namespace base_internal
 }  // namespace absl
 
-#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \
-  ((reinterpret_cast<const ::absl::internal::Unaligned16Struct *>(_p))->value)
-#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) \
-  ((reinterpret_cast<const ::absl::internal::Unaligned32Struct *>(_p))->value)
+#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p)                                  \
+  ((reinterpret_cast<const ::absl::base_internal::Unaligned16Struct *>(_p)) \
+       ->value)
+#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p)                                  \
+  ((reinterpret_cast<const ::absl::base_internal::Unaligned32Struct *>(_p)) \
+       ->value)
 
-#define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val)                          \
-  ((reinterpret_cast< ::absl::internal::Unaligned16Struct *>(_p))->value = \
-       (_val))
-#define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val)                          \
-  ((reinterpret_cast< ::absl::internal::Unaligned32Struct *>(_p))->value = \
-       (_val))
+#define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val)                      \
+  ((reinterpret_cast< ::absl::base_internal::Unaligned16Struct *>(_p)) \
+       ->value = (_val))
+#define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val)                      \
+  ((reinterpret_cast< ::absl::base_internal::Unaligned32Struct *>(_p)) \
+       ->value = (_val))
 
 namespace absl {
+namespace base_internal {
 
 inline uint64_t UnalignedLoad64(const void *p) {
   uint64_t t;
@@ -236,11 +249,13 @@ inline uint64_t UnalignedLoad64(const void *p) {
 
 inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); }
 
+}  // namespace base_internal
 }  // namespace absl
 
-#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) (absl::UnalignedLoad64(_p))
+#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) \
+  (absl::base_internal::UnalignedLoad64(_p))
 #define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \
-  (absl::UnalignedStore64(_p, _val))
+  (absl::base_internal::UnalignedStore64(_p, _val))
 
 #else
 
@@ -252,6 +267,7 @@ inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); }
 // unaligned loads and stores.
 
 namespace absl {
+namespace base_internal {
 
 inline uint16_t UnalignedLoad16(const void *p) {
   uint16_t t;
@@ -277,18 +293,22 @@ inline void UnalignedStore32(void *p, uint32_t v) { memcpy(p, &v, sizeof v); }
 
 inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); }
 
+}  // namespace base_internal
 }  // namespace absl
 
-#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) (absl::UnalignedLoad16(_p))
-#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) (absl::UnalignedLoad32(_p))
-#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) (absl::UnalignedLoad64(_p))
+#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \
+  (absl::base_internal::UnalignedLoad16(_p))
+#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) \
+  (absl::base_internal::UnalignedLoad32(_p))
+#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) \
+  (absl::base_internal::UnalignedLoad64(_p))
 
 #define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val) \
-  (absl::UnalignedStore16(_p, _val))
+  (absl::base_internal::UnalignedStore16(_p, _val))
 #define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \
-  (absl::UnalignedStore32(_p, _val))
+  (absl::base_internal::UnalignedStore32(_p, _val))
 #define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \
-  (absl::UnalignedStore64(_p, _val))
+  (absl::base_internal::UnalignedStore64(_p, _val))
 
 #endif
 
diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel
index 265c5ec9c418..f2210e3c1979 100644
--- a/absl/container/BUILD.bazel
+++ b/absl/container/BUILD.bazel
@@ -67,6 +67,7 @@ cc_test(
     deps = [
         ":fixed_array",
         "//absl/base:exception_testing",
+        "//absl/hash:hash_testing",
         "//absl/memory",
         "@com_google_googletest//:gtest_main",
     ],
@@ -79,6 +80,7 @@ cc_test(
     deps = [
         ":fixed_array",
         "//absl/base:exception_testing",
+        "//absl/hash:hash_testing",
         "//absl/memory",
         "@com_google_googletest//:gtest_main",
     ],
@@ -130,6 +132,7 @@ cc_test(
         "//absl/base",
         "//absl/base:core_headers",
         "//absl/base:exception_testing",
+        "//absl/hash:hash_testing",
         "//absl/memory",
         "//absl/strings",
         "@com_google_googletest//:gtest_main",
@@ -146,6 +149,7 @@ cc_test(
         "//absl/base",
         "//absl/base:core_headers",
         "//absl/base:exception_testing",
+        "//absl/hash:hash_testing",
         "//absl/memory",
         "//absl/strings",
         "@com_google_googletest//:gtest_main",
diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt
index 455c6f6cf625..9e406902b058 100644
--- a/absl/container/CMakeLists.txt
+++ b/absl/container/CMakeLists.txt
@@ -47,6 +47,7 @@ list(APPEND CONTAINER_INTERNAL_HEADERS
   "internal/unordered_set_modifiers_test.h"
 )
 
+
 absl_library(
   TARGET
     absl_container
diff --git a/absl/container/fixed_array.h b/absl/container/fixed_array.h
index d716380a5e27..fe67dceef669 100644
--- a/absl/container/fixed_array.h
+++ b/absl/container/fixed_array.h
@@ -358,6 +358,13 @@ class FixedArray {
   friend bool operator>=(const FixedArray& lhs, const FixedArray& rhs) {
     return !(lhs < rhs);
   }
+
+  template <typename H>
+  friend H AbslHashValue(H h, const FixedArray& v) {
+    return H::combine(H::combine_contiguous(std::move(h), v.data(), v.size()),
+                      v.size());
+  }
+
  private:
   // StorageElement
   //
diff --git a/absl/container/fixed_array_test.cc b/absl/container/fixed_array_test.cc
index b07ebcb6d9ca..205ff41fe114 100644
--- a/absl/container/fixed_array_test.cc
+++ b/absl/container/fixed_array_test.cc
@@ -27,6 +27,7 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include "absl/base/internal/exception_testing.h"
+#include "absl/hash/hash_testing.h"
 #include "absl/memory/memory.h"
 
 using ::testing::ElementsAreArray;
@@ -867,4 +868,5 @@ TEST(FixedArrayTest, AddressSanitizerAnnotations4) {
   EXPECT_DEATH(raw[21] = ThreeInts(), "container-overflow");
 }
 #endif  // ADDRESS_SANITIZER
+
 }  // namespace
diff --git a/absl/container/flat_hash_map.h b/absl/container/flat_hash_map.h
index 13fbfba51f48..9e7f682180e5 100644
--- a/absl/container/flat_hash_map.h
+++ b/absl/container/flat_hash_map.h
@@ -206,7 +206,7 @@ class flat_hash_map : public absl::container_internal::raw_hash_map<
   //   insertion) and a bool denoting whether the insertion took place.
   //
   // std::pair<iterator,bool> insert(T&& value):
-  // std::pair<iterator,bool> insert(init_type&& value ):
+  // std::pair<iterator,bool> insert(init_type&& value):
   //
   //   Inserts a moveable value into the `flat_hash_map`. Returns a pair
   //   consisting of an iterator to the inserted element (or to the element that
@@ -215,14 +215,14 @@ class flat_hash_map : public absl::container_internal::raw_hash_map<
   //
   // iterator insert(const_iterator hint, const init_type& value):
   // iterator insert(const_iterator hint, T&& value):
-  // iterator insert(const_iterator hint, init_type&& value );
+  // iterator insert(const_iterator hint, init_type&& value);
   //
   //   Inserts a value, using the position of `hint` as a non-binding suggestion
   //   for where to begin the insertion search. Returns an iterator to the
   //   inserted element, or to the existing element that prevented the
   //   insertion.
   //
-  // void insert(InputIterator first, InputIterator last ):
+  // void insert(InputIterator first, InputIterator last):
   //
   //   Inserts a range of values [`first`, `last`).
   //
@@ -230,7 +230,7 @@ class flat_hash_map : public absl::container_internal::raw_hash_map<
   //   multiple keys compare equivalently, for `flat_hash_map` we guarantee the
   //   first match is inserted.
   //
-  // void insert(std::initializer_list<init_type> ilist ):
+  // void insert(std::initializer_list<init_type> ilist):
   //
   //   Inserts the elements within the initializer list `ilist`.
   //
@@ -423,12 +423,12 @@ class flat_hash_map : public absl::container_internal::raw_hash_map<
   // iterators are invalidated. Otherwise iterators are not affected and
   // references are not invalidated. Overloads are listed below.
   //
-  // T& operator[](const Key& key ):
+  // T& operator[](const Key& key):
   //
   //   Inserts an init_type object constructed in-place if the element with the
   //   given key does not exist.
   //
-  // T& operator[]( Key&& key ):
+  // T& operator[](Key&& key):
   //
   //   Inserts an init_type object constructed in-place provided that an element
   //   with the given key does not exist.
diff --git a/absl/container/flat_hash_set.h b/absl/container/flat_hash_set.h
index ccd03a4abb6d..98aead1a8ae2 100644
--- a/absl/container/flat_hash_set.h
+++ b/absl/container/flat_hash_set.h
@@ -213,7 +213,7 @@ class flat_hash_set
   //   inserted element, or to the existing element that prevented the
   //   insertion.
   //
-  // void insert(InputIterator first, InputIterator last ):
+  // void insert(InputIterator first, InputIterator last):
   //
   //   Inserts a range of values [`first`, `last`).
   //
@@ -221,7 +221,7 @@ class flat_hash_set
   //   multiple keys compare equivalently, for `flat_hash_set` we guarantee the
   //   first match is inserted.
   //
-  // void insert(std::initializer_list<T> ilist ):
+  // void insert(std::initializer_list<T> ilist):
   //
   //   Inserts the elements within the initializer list `ilist`.
   //
diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h
index 0c0ffb0b1366..12756bb820cf 100644
--- a/absl/container/inlined_vector.h
+++ b/absl/container/inlined_vector.h
@@ -620,6 +620,12 @@ class InlinedVector {
   // Returns the allocator of this inlined vector.
   allocator_type get_allocator() const { return allocator(); }
 
+  template <typename H>
+  friend H AbslHashValue(H h, const InlinedVector& v) {
+    return H::combine(H::combine_contiguous(std::move(h), v.data(), v.size()),
+                      v.size());
+  }
+
  private:
   static_assert(N > 0, "inlined vector with nonpositive size");
 
diff --git a/absl/container/inlined_vector_test.cc b/absl/container/inlined_vector_test.cc
index 196a1bed976c..08dcd3ef66fb 100644
--- a/absl/container/inlined_vector_test.cc
+++ b/absl/container/inlined_vector_test.cc
@@ -31,6 +31,7 @@
 #include "absl/base/internal/raw_logging.h"
 #include "absl/base/macros.h"
 #include "absl/container/internal/test_instance_tracker.h"
+#include "absl/hash/hash_testing.h"
 #include "absl/memory/memory.h"
 #include "absl/strings/str_cat.h"
 
@@ -1788,4 +1789,5 @@ TEST(AllocatorSupportTest, SizeAllocConstructor) {
     EXPECT_THAT(v, AllOf(SizeIs(len), Each(0)));
   }
 }
+
 }  // anonymous namespace
diff --git a/absl/container/internal/hash_function_defaults.h b/absl/container/internal/hash_function_defaults.h
index dd6cd8f537fd..1f0d794d9663 100644
--- a/absl/container/internal/hash_function_defaults.h
+++ b/absl/container/internal/hash_function_defaults.h
@@ -83,11 +83,6 @@ struct StringHashEq {
     }
   };
 };
-
-#if defined(HAS_GLOBAL_STRING)
-template <>
-struct HashEq<std::string> : StringHashEq {};
-#endif
 template <>
 struct HashEq<std::string> : StringHashEq {};
 template <>
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h
index 0c0e5906d206..70da90f79a4f 100644
--- a/absl/container/internal/raw_hash_set.h
+++ b/absl/container/internal/raw_hash_set.h
@@ -1330,8 +1330,7 @@ class raw_hash_set {
   void rehash(size_t n) {
     if (n == 0 && capacity_ == 0) return;
     if (n == 0 && size_ == 0) return destroy_slots();
-    auto m = NormalizeCapacity(std::max(
-        n, static_cast<size_t>(std::ceil(size() / kMaxLoadFactor))));
+    auto m = NormalizeCapacity(std::max(n, NumSlotsFast(size())));
     // n == 0 unconditionally rehashes as per the standard.
     if (n == 0 || m > capacity_) {
       resize(m);
@@ -1339,7 +1338,7 @@ class raw_hash_set {
   }
 
   void reserve(size_t n) {
-    rehash(static_cast<size_t>(std::ceil(n / kMaxLoadFactor)));
+    rehash(NumSlotsFast(n));
   }
 
   // Extension API: support for heterogeneous keys.
@@ -1518,6 +1517,13 @@ class raw_hash_set {
     slot_type&& slot;
   };
 
+  // Computes std::ceil(n / kMaxLoadFactor). Faster than calling std::ceil.
+  static inline size_t NumSlotsFast(size_t n) {
+    return static_cast<size_t>(
+        (n * kMaxLoadFactorDenominator + (kMaxLoadFactorNumerator - 1)) /
+        kMaxLoadFactorNumerator);
+  }
+
   // "erases" the object from the container, except that it doesn't actually
   // destroy the object. It only updates all the metadata of the class.
   // This can be used in conjunction with Policy::transfer to move the object to
@@ -1825,7 +1831,10 @@ class raw_hash_set {
   }
 
   // On average each group has 2 empty slot (for the vectorized case).
-  static constexpr float kMaxLoadFactor = 14.0 / 16.0;
+  static constexpr int64_t kMaxLoadFactorNumerator = 14;
+  static constexpr int64_t kMaxLoadFactorDenominator = 16;
+  static constexpr float kMaxLoadFactor =
+      1.0 * kMaxLoadFactorNumerator / kMaxLoadFactorDenominator;
 
   // TODO(alkis): Investigate removing some of these fields:
   // - ctrl/slots can be derived from each other
diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc
index f59a19b4a62d..cd33a3acb917 100644
--- a/absl/container/internal/raw_hash_set_test.cc
+++ b/absl/container/internal/raw_hash_set_test.cc
@@ -1916,7 +1916,7 @@ TEST(Table, EffectiveLoadFactorInts) {
 }
 
 // Confirm that we assert if we try to erase() end().
-TEST(Table, EraseOfEndAsserts) {
+TEST(TableDeathTest, EraseOfEndAsserts) {
   // Use an assert with side-effects to figure out if they are actually enabled.
   bool assert_enabled = false;
   assert([&]() {
@@ -1928,7 +1928,7 @@ TEST(Table, EraseOfEndAsserts) {
   IntTable t;
   // Extra simple "regexp" as regexp support is highly varied across platforms.
   constexpr char kDeathMsg[] = "it != end";
-  EXPECT_DEATH(t.erase(t.end()), kDeathMsg);
+  EXPECT_DEATH_IF_SUPPORTED(t.erase(t.end()), kDeathMsg);
 }
 
 #ifdef ADDRESS_SANITIZER
diff --git a/absl/container/node_hash_map.h b/absl/container/node_hash_map.h
index 3c7de1e8885f..6369ec3ad643 100644
--- a/absl/container/node_hash_map.h
+++ b/absl/container/node_hash_map.h
@@ -201,7 +201,7 @@ class node_hash_map
   //   insertion) and a `bool` denoting whether the insertion took place.
   //
   // std::pair<iterator,bool> insert(T&& value):
-  // std::pair<iterator,bool> insert(init_type&& value ):
+  // std::pair<iterator,bool> insert(init_type&& value):
   //
   //   Inserts a moveable value into the `node_hash_map`. Returns a `std::pair`
   //   consisting of an iterator to the inserted element (or to the element that
@@ -210,14 +210,14 @@ class node_hash_map
   //
   // iterator insert(const_iterator hint, const init_type& value):
   // iterator insert(const_iterator hint, T&& value):
-  // iterator insert(const_iterator hint, init_type&& value );
+  // iterator insert(const_iterator hint, init_type&& value);
   //
   //   Inserts a value, using the position of `hint` as a non-binding suggestion
   //   for where to begin the insertion search. Returns an iterator to the
   //   inserted element, or to the existing element that prevented the
   //   insertion.
   //
-  // void insert(InputIterator first, InputIterator last ):
+  // void insert(InputIterator first, InputIterator last):
   //
   //   Inserts a range of values [`first`, `last`).
   //
@@ -225,7 +225,7 @@ class node_hash_map
   //   multiple keys compare equivalently, for `node_hash_map` we guarantee the
   //   first match is inserted.
   //
-  // void insert(std::initializer_list<init_type> ilist ):
+  // void insert(std::initializer_list<init_type> ilist):
   //
   //   Inserts the elements within the initializer list `ilist`.
   //
@@ -413,12 +413,12 @@ class node_hash_map
   // all iterators are invalidated. Otherwise iterators are not affected and
   // references are not invalidated. Overloads are listed below.
   //
-  // T& operator[](const Key& key ):
+  // T& operator[](const Key& key):
   //
   //   Inserts an init_type object constructed in-place if the element with the
   //   given key does not exist.
   //
-  // T& operator[]( Key&& key ):
+  // T& operator[](Key&& key):
   //
   //   Inserts an init_type object constructed in-place provided that an element
   //   with the given key does not exist.
diff --git a/absl/container/node_hash_set.h b/absl/container/node_hash_set.h
index 927a454cffbe..90d4ce0c1631 100644
--- a/absl/container/node_hash_set.h
+++ b/absl/container/node_hash_set.h
@@ -207,7 +207,7 @@ class node_hash_set
   //   inserted element, or to the existing element that prevented the
   //   insertion.
   //
-  // void insert(InputIterator first, InputIterator last ):
+  // void insert(InputIterator first, InputIterator last):
   //
   //   Inserts a range of values [`first`, `last`).
   //
@@ -215,7 +215,7 @@ class node_hash_set
   //   multiple keys compare equivalently, for `node_hash_set` we guarantee the
   //   first match is inserted.
   //
-  // void insert(std::initializer_list<T> ilist ):
+  // void insert(std::initializer_list<T> ilist):
   //
   //   Inserts the elements within the initializer list `ilist`.
   //
diff --git a/absl/copts.bzl b/absl/copts.bzl
index 717f5a457b4d..5c508f17df97 100644
--- a/absl/copts.bzl
+++ b/absl/copts.bzl
@@ -53,6 +53,10 @@ LLVM_FLAGS = [
     "-Wno-packed",
     "-Wno-padded",
     ###
+    # Google style does not use unsigned integers, though STL containers
+    # have unsigned types.
+    "-Wno-sign-compare",
+    ###
     "-Wno-float-conversion",
     "-Wno-float-equal",
     "-Wno-format-nonliteral",
@@ -100,6 +104,7 @@ LLVM_TEST_FLAGS = [
     "-Wno-c99-extensions",
     "-Wno-missing-noreturn",
     "-Wno-missing-prototypes",
+    "-Wno-missing-variable-declarations",
     "-Wno-null-conversion",
     "-Wno-shadow",
     "-Wno-shift-sign-overflow",
@@ -111,6 +116,8 @@ LLVM_TEST_FLAGS = [
     "-Wno-unused-template",
     "-Wno-used-but-marked-unused",
     "-Wno-zero-as-null-pointer-constant",
+    # gtest depends on this GNU extension being offered.
+    "-Wno-gnu-zero-variadic-macro-arguments",
 ]
 
 MSVC_FLAGS = [
diff --git a/absl/hash/internal/city.cc b/absl/hash/internal/city.cc
index 591017abbea4..8f72dd1b7d0c 100644
--- a/absl/hash/internal/city.cc
+++ b/absl/hash/internal/city.cc
@@ -129,6 +129,7 @@ uint32_t CityHash32(const char *s, size_t len) {
 
   // len > 24
   uint32_t h = len, g = c1 * len, f = g;
+
   uint32_t a0 = Rotate32(Fetch32(s + len - 4) * c1, 17) * c2;
   uint32_t a1 = Rotate32(Fetch32(s + len - 8) * c1, 17) * c2;
   uint32_t a2 = Rotate32(Fetch32(s + len - 16) * c1, 17) * c2;
@@ -151,28 +152,28 @@ uint32_t CityHash32(const char *s, size_t len) {
   f = f * 5 + 0xe6546b64;
   size_t iters = (len - 1) / 20;
   do {
-    uint32_t a0 = Rotate32(Fetch32(s) * c1, 17) * c2;
-    uint32_t a1 = Fetch32(s + 4);
-    uint32_t a2 = Rotate32(Fetch32(s + 8) * c1, 17) * c2;
-    uint32_t a3 = Rotate32(Fetch32(s + 12) * c1, 17) * c2;
-    uint32_t a4 = Fetch32(s + 16);
-    h ^= a0;
+    uint32_t b0 = Rotate32(Fetch32(s) * c1, 17) * c2;
+    uint32_t b1 = Fetch32(s + 4);
+    uint32_t b2 = Rotate32(Fetch32(s + 8) * c1, 17) * c2;
+    uint32_t b3 = Rotate32(Fetch32(s + 12) * c1, 17) * c2;
+    uint32_t b4 = Fetch32(s + 16);
+    h ^= b0;
     h = Rotate32(h, 18);
     h = h * 5 + 0xe6546b64;
-    f += a1;
+    f += b1;
     f = Rotate32(f, 19);
     f = f * c1;
-    g += a2;
+    g += b2;
     g = Rotate32(g, 18);
     g = g * 5 + 0xe6546b64;
-    h ^= a3 + a1;
+    h ^= b3 + b1;
     h = Rotate32(h, 19);
     h = h * 5 + 0xe6546b64;
-    g ^= a4;
+    g ^= b4;
     g = absl::gbswap_32(g) * 5;
-    h += a4 * 5;
+    h += b4 * 5;
     h = absl::gbswap_32(h);
-    f += a0;
+    f += b0;
     PERMUTE3(f, h, g);
     s += 20;
   } while (--iters != 0);
diff --git a/absl/numeric/BUILD.bazel b/absl/numeric/BUILD.bazel
index f49571ebb3e1..324ce6695e40 100644
--- a/absl/numeric/BUILD.bazel
+++ b/absl/numeric/BUILD.bazel
@@ -49,6 +49,7 @@ cc_test(
         ":int128",
         "//absl/base",
         "//absl/base:core_headers",
+        "//absl/hash:hash_testing",
         "//absl/meta:type_traits",
         "@com_google_googletest//:gtest_main",
     ],
diff --git a/absl/numeric/int128.h b/absl/numeric/int128.h
index 2d131b8bda1c..79b62a758669 100644
--- a/absl/numeric/int128.h
+++ b/absl/numeric/int128.h
@@ -192,6 +192,12 @@ class
   // Returns the highest value for a 128-bit unsigned integer.
   friend constexpr uint128 Uint128Max();
 
+  // Support for absl::Hash.
+  template <typename H>
+  friend H AbslHashValue(H h, uint128 v) {
+    return H::combine(std::move(h), Uint128High64(v), Uint128Low64(v));
+  }
+
  private:
   constexpr uint128(uint64_t high, uint64_t low);
 
diff --git a/absl/numeric/int128_test.cc b/absl/numeric/int128_test.cc
index 1eb3e0ec8961..dfe3475aca06 100644
--- a/absl/numeric/int128_test.cc
+++ b/absl/numeric/int128_test.cc
@@ -23,6 +23,7 @@
 
 #include "gtest/gtest.h"
 #include "absl/base/internal/cycleclock.h"
+#include "absl/hash/hash_testing.h"
 #include "absl/meta/type_traits.h"
 
 #if defined(_MSC_VER) && _MSC_VER == 1900
diff --git a/absl/synchronization/BUILD.bazel b/absl/synchronization/BUILD.bazel
index 4f6a70740c2e..f52e9d41644a 100644
--- a/absl/synchronization/BUILD.bazel
+++ b/absl/synchronization/BUILD.bazel
@@ -88,6 +88,9 @@ cc_test(
     size = "small",
     srcs = ["barrier_test.cc"],
     copts = ABSL_TEST_COPTS,
+    tags = [
+        "no_test_wasm",
+    ],
     deps = [
         ":synchronization",
         "//absl/time",
@@ -100,6 +103,9 @@ cc_test(
     size = "small",
     srcs = ["blocking_counter_test.cc"],
     copts = ABSL_TEST_COPTS,
+    tags = [
+        "no_test_wasm",
+    ],
     deps = [
         ":synchronization",
         "//absl/time",
@@ -209,6 +215,7 @@ cc_test(
     name = "per_thread_sem_test",
     size = "medium",
     copts = ABSL_TEST_COPTS,
+    tags = ["no_test_wasm"],
     deps = [
         ":per_thread_sem_test_common",
         ":synchronization",
diff --git a/absl/time/time.h b/absl/time/time.h
index 2f0fda4cb07c..50bf971df0a2 100644
--- a/absl/time/time.h
+++ b/absl/time/time.h
@@ -163,6 +163,11 @@ class Duration {
   Duration& operator*=(float r) { return *this *= static_cast<double>(r); }
   Duration& operator/=(float r) { return *this /= static_cast<double>(r); }
 
+  template <typename H>
+  friend H AbslHashValue(H h, Duration d) {
+    return H::combine(std::move(h), d.rep_hi_, d.rep_lo_);
+  }
+
  private:
   friend constexpr int64_t time_internal::GetRepHi(Duration d);
   friend constexpr uint32_t time_internal::GetRepLo(Duration d);
@@ -611,6 +616,11 @@ class Time {
   // Returns the breakdown of this instant in the given TimeZone.
   Breakdown In(TimeZone tz) const;
 
+  template <typename H>
+  friend H AbslHashValue(H h, Time t) {
+    return H::combine(std::move(h), t.rep_);
+  }
+
  private:
   friend constexpr Time time_internal::FromUnixDuration(Duration d);
   friend constexpr Duration time_internal::ToUnixDuration(Time t);
@@ -1059,6 +1069,11 @@ class TimeZone {
 
   std::string name() const { return cz_.name(); }
 
+  template <typename H>
+  friend H AbslHashValue(H h, TimeZone tz) {
+    return H::combine(std::move(h), tz.cz_);
+  }
+
  private:
   friend bool operator==(TimeZone a, TimeZone b) { return a.cz_ == b.cz_; }
   friend bool operator!=(TimeZone a, TimeZone b) { return a.cz_ != b.cz_; }
diff --git a/absl/types/BUILD.bazel b/absl/types/BUILD.bazel
index 7841a97d985a..32f690c94c1d 100644
--- a/absl/types/BUILD.bazel
+++ b/absl/types/BUILD.bazel
@@ -136,6 +136,7 @@ cc_test(
         "//absl/base:exception_testing",
         "//absl/container:fixed_array",
         "//absl/container:inlined_vector",
+        "//absl/hash:hash_testing",
         "//absl/strings",
         "@com_google_googletest//:gtest_main",
     ],
@@ -153,6 +154,7 @@ cc_test(
         "//absl/base:exception_testing",
         "//absl/container:fixed_array",
         "//absl/container:inlined_vector",
+        "//absl/hash:hash_testing",
         "//absl/strings",
         "@com_google_googletest//:gtest_main",
     ],
diff --git a/absl/types/span.h b/absl/types/span.h
index 3359ce5093c5..911af0c57a61 100644
--- a/absl/types/span.h
+++ b/absl/types/span.h
@@ -485,6 +485,13 @@ class Span {
                : (base_internal::ThrowStdOutOfRange("pos > size()"), Span());
   }
 
+  // Support for absl::Hash.
+  template <typename H>
+  friend H AbslHashValue(H h, Span v) {
+    return H::combine(H::combine_contiguous(std::move(h), v.data(), v.size()),
+                      v.size());
+  }
+
  private:
   pointer ptr_;
   size_type len_;
diff --git a/absl/types/span_test.cc b/absl/types/span_test.cc
index fbce7e874798..bd739ff2a070 100644
--- a/absl/types/span_test.cc
+++ b/absl/types/span_test.cc
@@ -29,6 +29,7 @@
 #include "absl/base/internal/exception_testing.h"
 #include "absl/container/fixed_array.h"
 #include "absl/container/inlined_vector.h"
+#include "absl/hash/hash_testing.h"
 #include "absl/strings/str_cat.h"
 
 namespace {