diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel
index 5e67a65..83fd607 100644
--- a/absl/base/BUILD.bazel
+++ b/absl/base/BUILD.bazel
@@ -699,8 +699,9 @@
     ],
 )
 
-cc_test(
+cc_binary(
     name = "thread_identity_benchmark",
+    testonly = True,
     srcs = ["internal/thread_identity_benchmark.cc"],
     copts = ABSL_TEST_COPTS,
     linkopts = ABSL_DEFAULT_LINKOPTS,
@@ -710,7 +711,6 @@
         ":base",
         "//absl/synchronization",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
diff --git a/absl/base/internal/thread_identity_benchmark.cc b/absl/base/internal/thread_identity_benchmark.cc
index 0ae10f2..419e82d 100644
--- a/absl/base/internal/thread_identity_benchmark.cc
+++ b/absl/base/internal/thread_identity_benchmark.cc
@@ -12,10 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "benchmark/benchmark.h"
 #include "absl/base/internal/thread_identity.h"
 #include "absl/synchronization/internal/create_thread_identity.h"
 #include "absl/synchronization/internal/per_thread_sem.h"
+#include "benchmark/benchmark.h"
 
 namespace {
 
diff --git a/absl/base/nullability.h b/absl/base/nullability.h
index 37e910a..d11da57 100644
--- a/absl/base/nullability.h
+++ b/absl/base/nullability.h
@@ -220,7 +220,8 @@
 // No-op except for being a human readable signal.
 #define ABSL_POINTERS_DEFAULT_NONNULL
 
-#if defined(__clang__) && !defined(__OBJC__)
+#if defined(__clang__) && !defined(__OBJC__) && \
+    ABSL_HAVE_FEATURE(nullability_on_classes)
 // absl_nonnull (default with `ABSL_POINTERS_DEFAULT_NONNULL`)
 //
 // The indicated pointer is never null. It is the responsibility of the provider
diff --git a/absl/base/nullability_test.cc b/absl/base/nullability_test.cc
index 028ea6c..b4a22e8 100644
--- a/absl/base/nullability_test.cc
+++ b/absl/base/nullability_test.cc
@@ -16,15 +16,85 @@
 
 #include <cassert>
 #include <memory>
+#include <type_traits>
 #include <utility>
 
 #include "gtest/gtest.h"
-#include "absl/base/attributes.h"
 
 namespace {
+namespace macro_annotations {
+void funcWithNonnullArg(int* absl_nonnull /*arg*/) {}
+template <typename T>
+void funcWithDeducedNonnullArg(T* absl_nonnull /*arg*/) {}
+
+TEST(NonnullTest, NonnullArgument) {
+  int var = 0;
+  funcWithNonnullArg(&var);
+  funcWithDeducedNonnullArg(&var);
+}
+
+int* absl_nonnull funcWithNonnullReturn() {
+  static int var = 0;
+  return &var;
+}
+
+TEST(NonnullTest, NonnullReturn) {
+  auto var = funcWithNonnullReturn();
+  (void)var;
+}
+
+TEST(PassThroughTest, PassesThroughRawPointerToInt) {
+  EXPECT_TRUE((std::is_same<int* absl_nonnull, int*>::value));
+  EXPECT_TRUE((std::is_same<int* absl_nullable, int*>::value));
+  EXPECT_TRUE((std::is_same<int* absl_nullability_unknown, int*>::value));
+}
+
+TEST(PassThroughTest, PassesThroughRawPointerToVoid) {
+  EXPECT_TRUE((std::is_same<void* absl_nonnull, void*>::value));
+  EXPECT_TRUE((std::is_same<void* absl_nullable, void*>::value));
+  EXPECT_TRUE((std::is_same<void* absl_nullability_unknown, void*>::value));
+}
+
+TEST(PassThroughTest, PassesThroughUniquePointerToInt) {
+  using T = std::unique_ptr<int>;
+  EXPECT_TRUE((std::is_same<absl_nonnull T, T>::value));
+  EXPECT_TRUE((std::is_same<absl_nullable T, T>::value));
+  EXPECT_TRUE((std::is_same<absl_nullability_unknown T, T>::value));
+}
+
+TEST(PassThroughTest, PassesThroughSharedPointerToInt) {
+  using T = std::shared_ptr<int>;
+  EXPECT_TRUE((std::is_same<absl_nonnull T, T>::value));
+  EXPECT_TRUE((std::is_same<absl_nullable T, T>::value));
+  EXPECT_TRUE((std::is_same<absl_nullability_unknown T, T>::value));
+}
+
+TEST(PassThroughTest, PassesThroughSharedPointerToVoid) {
+  using T = std::shared_ptr<void>;
+  EXPECT_TRUE((std::is_same<absl_nonnull T, T>::value));
+  EXPECT_TRUE((std::is_same<absl_nullable T, T>::value));
+  EXPECT_TRUE((std::is_same<absl_nullability_unknown T, T>::value));
+}
+
+TEST(PassThroughTest, PassesThroughPointerToMemberObject) {
+  using T = decltype(&std::pair<int, int>::first);
+  EXPECT_TRUE((std::is_same<absl_nonnull T, T>::value));
+  EXPECT_TRUE((std::is_same<absl_nullable T, T>::value));
+  EXPECT_TRUE((std::is_same<absl_nullability_unknown T, T>::value));
+}
+
+TEST(PassThroughTest, PassesThroughPointerToMemberFunction) {
+  using T = decltype(&std::unique_ptr<int>::reset);
+  EXPECT_TRUE((std::is_same<absl_nonnull T, T>::value));
+  EXPECT_TRUE((std::is_same<absl_nullable T, T>::value));
+  EXPECT_TRUE((std::is_same<absl_nullability_unknown T, T>::value));
+}
+}  // namespace macro_annotations
+
 using ::absl::Nonnull;
 using ::absl::NullabilityUnknown;
 using ::absl::Nullable;
+namespace type_alias_annotations {
 
 void funcWithNonnullArg(Nonnull<int*> /*arg*/) {}
 template <typename T>
@@ -93,6 +163,7 @@
   EXPECT_TRUE((std::is_same<NullabilityUnknown<T>, T>::value));
 }
 
+}  // namespace type_alias_annotations
 }  // namespace
 
 // Nullable ADL lookup test
diff --git a/absl/cleanup/internal/cleanup.h b/absl/cleanup/internal/cleanup.h
index 967513a..4dd6f91 100644
--- a/absl/cleanup/internal/cleanup.h
+++ b/absl/cleanup/internal/cleanup.h
@@ -88,7 +88,7 @@
 
  private:
   bool is_callback_engaged_;
-  alignas(Callback) char callback_buffer_[sizeof(Callback)];
+  alignas(Callback) unsigned char callback_buffer_[sizeof(Callback)];
 };
 
 }  // namespace cleanup_internal
diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel
index 37b5f2a..ccaed1c 100644
--- a/absl/container/BUILD.bazel
+++ b/absl/container/BUILD.bazel
@@ -1148,6 +1148,5 @@
         "//absl/strings:str_format",
         "//absl/time",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
diff --git a/absl/container/btree_benchmark.cc b/absl/container/btree_benchmark.cc
index b1525bd..ee4efbd 100644
--- a/absl/container/btree_benchmark.cc
+++ b/absl/container/btree_benchmark.cc
@@ -26,7 +26,6 @@
 #include <unordered_set>
 #include <vector>
 
-#include "benchmark/benchmark.h"
 #include "absl/algorithm/container.h"
 #include "absl/base/internal/raw_logging.h"
 #include "absl/container/btree_map.h"
@@ -42,6 +41,7 @@
 #include "absl/strings/cord.h"
 #include "absl/strings/str_format.h"
 #include "absl/time/time.h"
+#include "benchmark/benchmark.h"
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
diff --git a/absl/container/fixed_array.h b/absl/container/fixed_array.h
index b213eb1..8bf8e6c 100644
--- a/absl/container/fixed_array.h
+++ b/absl/container/fixed_array.h
@@ -447,7 +447,8 @@
 
    private:
     ABSL_ADDRESS_SANITIZER_REDZONE(redzone_begin_);
-    alignas(StorageElement) char buff_[sizeof(StorageElement[inline_elements])];
+    alignas(StorageElement) unsigned char buff_[sizeof(
+        StorageElement[inline_elements])];
     ABSL_ADDRESS_SANITIZER_REDZONE(redzone_end_);
   };
 
diff --git a/absl/container/internal/inlined_vector.h b/absl/container/internal/inlined_vector.h
index a3b14a2..b0d3f07 100644
--- a/absl/container/internal/inlined_vector.h
+++ b/absl/container/internal/inlined_vector.h
@@ -543,7 +543,7 @@
       (std::max)(N, sizeof(Allocated) / sizeof(ValueType<A>));
 
   struct Inlined {
-    alignas(ValueType<A>) char inlined_data[sizeof(
+    alignas(ValueType<A>) unsigned char inlined_data[sizeof(
         ValueType<A>[kOptimalInlinedSize])];
   };
 
diff --git a/absl/crc/crc32c_benchmark.cc b/absl/crc/crc32c_benchmark.cc
index 3b46ef3..d7cecc3 100644
--- a/absl/crc/crc32c_benchmark.cc
+++ b/absl/crc/crc32c_benchmark.cc
@@ -40,7 +40,13 @@
     benchmark::DoNotOptimize(crc);
   }
 }
-BENCHMARK(BM_Calculate)->Arg(0)->Arg(1)->Arg(100)->Arg(10000)->Arg(500000);
+BENCHMARK(BM_Calculate)
+    ->Arg(0)
+    ->Arg(1)
+    ->Arg(100)
+    ->Arg(2048)
+    ->Arg(10000)
+    ->Arg(500000);
 
 void BM_Extend(benchmark::State& state) {
   int len = state.range(0);
@@ -53,8 +59,14 @@
     benchmark::DoNotOptimize(crc);
   }
 }
-BENCHMARK(BM_Extend)->Arg(0)->Arg(1)->Arg(100)->Arg(10000)->Arg(500000)->Arg(
-    100 * 1000 * 1000);
+BENCHMARK(BM_Extend)
+    ->Arg(0)
+    ->Arg(1)
+    ->Arg(100)
+    ->Arg(2048)
+    ->Arg(10000)
+    ->Arg(500000)
+    ->Arg(100 * 1000 * 1000);
 
 // Make working set >> CPU cache size to benchmark prefetches better
 void BM_ExtendCacheMiss(benchmark::State& state) {
@@ -147,7 +159,8 @@
   state.SetBytesProcessed(static_cast<int64_t>(state.iterations()) *
                           state.range(0));
 }
-BENCHMARK(BM_Memcpy)->Arg(0)->Arg(1)->Arg(100)->Arg(10000)->Arg(500000);
+BENCHMARK(BM_Memcpy)->Arg(0)->Arg(1)->Arg(100)->Arg(2048)->Arg(10000)->Arg(
+    500000);
 
 void BM_RemoveSuffix(benchmark::State& state) {
   int full_string_len = state.range(0);
diff --git a/absl/crc/internal/crc32_x86_arm_combined_simd.h b/absl/crc/internal/crc32_x86_arm_combined_simd.h
index 0f6e347..5a9b61a 100644
--- a/absl/crc/internal/crc32_x86_arm_combined_simd.h
+++ b/absl/crc/internal/crc32_x86_arm_combined_simd.h
@@ -99,19 +99,12 @@
 // Produces a XOR operation of |l| and |r|.
 V128 V128_Xor(const V128 l, const V128 r);
 
-// Produces an AND operation of |l| and |r|.
-V128 V128_And(const V128 l, const V128 r);
-
 // Sets the lower half of a 128 bit register to the given 64-bit value and
 // zeroes the upper half.
 // dst[63:0] := |r|
 // dst[127:64] := |0|
 V128 V128_From64WithZeroFill(const uint64_t r);
 
-// Shift |l| right by |imm| bytes while shifting in zeros.
-template <int imm>
-V128 V128_ShiftRight(const V128 l);
-
 // Extracts a 32-bit integer from |l|, selected with |imm|.
 template <int imm>
 int V128_Extract32(const V128 l);
@@ -170,18 +163,11 @@
 
 inline V128 V128_Xor(const V128 l, const V128 r) { return _mm_xor_si128(l, r); }
 
-inline V128 V128_And(const V128 l, const V128 r) { return _mm_and_si128(l, r); }
-
 inline V128 V128_From64WithZeroFill(const uint64_t r) {
   return _mm_set_epi64x(static_cast<int64_t>(0), static_cast<int64_t>(r));
 }
 
 template <int imm>
-inline V128 V128_ShiftRight(const V128 l) {
-  return _mm_srli_si128(l, imm);
-}
-
-template <int imm>
 inline int V128_Extract32(const V128 l) {
   return _mm_extract_epi32(l, imm);
 }
@@ -261,8 +247,6 @@
 
 inline V128 V128_Xor(const V128 l, const V128 r) { return veorq_u64(l, r); }
 
-inline V128 V128_And(const V128 l, const V128 r) { return vandq_u64(l, r); }
-
 inline V128 V128_From64WithZeroFill(const uint64_t r){
   constexpr uint64x2_t kZero = {0, 0};
   return vsetq_lane_u64(r, kZero, 0);
@@ -270,12 +254,6 @@
 
 
 template <int imm>
-inline V128 V128_ShiftRight(const V128 l) {
-  return vreinterpretq_u64_s8(
-      vextq_s8(vreinterpretq_s8_u64(l), vdupq_n_s8(0), imm));
-}
-
-template <int imm>
 inline int V128_Extract32(const V128 l) {
   return vgetq_lane_s32(vreinterpretq_s32_u64(l), imm);
 }
diff --git a/absl/crc/internal/crc_x86_arm_combined.cc b/absl/crc/internal/crc_x86_arm_combined.cc
index 9817c73..3194bec 100644
--- a/absl/crc/internal/crc_x86_arm_combined.cc
+++ b/absl/crc/internal/crc_x86_arm_combined.cc
@@ -221,7 +221,8 @@
   // We are applying it to CRC32C polynomial.
   ABSL_ATTRIBUTE_ALWAYS_INLINE void Process64BytesPclmul(
       const uint8_t* p, V128* partialCRC) const {
-    V128 loopMultiplicands = V128_Load(reinterpret_cast<const V128*>(k1k2));
+    V128 loopMultiplicands =
+        V128_Load(reinterpret_cast<const V128*>(kFoldAcross512Bits));
 
     V128 partialCRC1 = partialCRC[0];
     V128 partialCRC2 = partialCRC[1];
@@ -265,53 +266,33 @@
 
     // Combine 4 vectors of partial crc into a single vector.
     V128 reductionMultiplicands =
-        V128_Load(reinterpret_cast<const V128*>(k5k6));
+        V128_Load(reinterpret_cast<const V128*>(kFoldAcross256Bits));
 
     V128 low = V128_PMulLow(reductionMultiplicands, partialCRC1);
     V128 high = V128_PMulHi(reductionMultiplicands, partialCRC1);
 
     partialCRC1 = V128_Xor(low, high);
-    partialCRC1 = V128_Xor(partialCRC1, partialCRC2);
+    partialCRC1 = V128_Xor(partialCRC1, partialCRC3);
 
-    low = V128_PMulLow(reductionMultiplicands, partialCRC3);
-    high = V128_PMulHi(reductionMultiplicands, partialCRC3);
+    low = V128_PMulLow(reductionMultiplicands, partialCRC2);
+    high = V128_PMulHi(reductionMultiplicands, partialCRC2);
 
-    partialCRC3 = V128_Xor(low, high);
-    partialCRC3 = V128_Xor(partialCRC3, partialCRC4);
+    partialCRC2 = V128_Xor(low, high);
+    partialCRC2 = V128_Xor(partialCRC2, partialCRC4);
 
-    reductionMultiplicands = V128_Load(reinterpret_cast<const V128*>(k3k4));
+    reductionMultiplicands =
+        V128_Load(reinterpret_cast<const V128*>(kFoldAcross128Bits));
 
     low = V128_PMulLow(reductionMultiplicands, partialCRC1);
     high = V128_PMulHi(reductionMultiplicands, partialCRC1);
     V128 fullCRC = V128_Xor(low, high);
-    fullCRC = V128_Xor(fullCRC, partialCRC3);
+    fullCRC = V128_Xor(fullCRC, partialCRC2);
 
     // Reduce fullCRC into scalar value.
-    reductionMultiplicands = V128_Load(reinterpret_cast<const V128*>(k5k6));
-
-    V128 mask = V128_Load(reinterpret_cast<const V128*>(kMask));
-
-    V128 tmp = V128_PMul01(reductionMultiplicands, fullCRC);
-    fullCRC = V128_ShiftRight<8>(fullCRC);
-    fullCRC = V128_Xor(fullCRC, tmp);
-
-    reductionMultiplicands = V128_Load(reinterpret_cast<const V128*>(k7k0));
-
-    tmp = V128_ShiftRight<4>(fullCRC);
-    fullCRC = V128_And(fullCRC, mask);
-    fullCRC = V128_PMulLow(reductionMultiplicands, fullCRC);
-    fullCRC = V128_Xor(tmp, fullCRC);
-
-    reductionMultiplicands = V128_Load(reinterpret_cast<const V128*>(kPoly));
-
-    tmp = V128_And(fullCRC, mask);
-    tmp = V128_PMul01(reductionMultiplicands, tmp);
-    tmp = V128_And(tmp, mask);
-    tmp = V128_PMulLow(reductionMultiplicands, tmp);
-
-    fullCRC = V128_Xor(tmp, fullCRC);
-
-    return static_cast<uint64_t>(V128_Extract32<1>(fullCRC));
+    uint32_t crc = 0;
+    crc = CRC32_u64(crc, V128_Extract64<0>(fullCRC));
+    crc = CRC32_u64(crc, V128_Extract64<1>(fullCRC));
+    return crc;
   }
 
   // Update crc with 64 bytes of data from p.
@@ -325,15 +306,23 @@
     return crc;
   }
 
-  // Generated by crc32c_x86_test --crc32c_generate_constants=true
-  // and verified against constants in linux kernel for S390:
-  // https://github.com/torvalds/linux/blob/master/arch/s390/crypto/crc32le-vx.S
-  alignas(16) static constexpr uint64_t k1k2[2] = {0x0740eef02, 0x09e4addf8};
-  alignas(16) static constexpr uint64_t k3k4[2] = {0x1384aa63a, 0x0ba4fc28e};
-  alignas(16) static constexpr uint64_t k5k6[2] = {0x0f20c0dfe, 0x14cd00bd6};
-  alignas(16) static constexpr uint64_t k7k0[2] = {0x0dd45aab8, 0x000000000};
-  alignas(16) static constexpr uint64_t kPoly[2] = {0x105ec76f0, 0x0dea713f1};
-  alignas(16) static constexpr uint32_t kMask[4] = {~0u, 0u, ~0u, 0u};
+  // Constants generated by './scripts/gen-crc-consts.py x86_pclmul
+  // crc32_lsb_0x82f63b78' from the Linux kernel.
+  alignas(16) static constexpr uint64_t kFoldAcross512Bits[2] = {
+      // (x^543 mod G) * x^32
+      0x00000000740eef02,
+      // (x^479 mod G) * x^32
+      0x000000009e4addf8};
+  alignas(16) static constexpr uint64_t kFoldAcross256Bits[2] = {
+      // (x^287 mod G) * x^32
+      0x000000003da6d0cb,
+      // (x^223 mod G) * x^32
+      0x00000000ba4fc28e};
+  alignas(16) static constexpr uint64_t kFoldAcross128Bits[2] = {
+      // (x^159 mod G) * x^32
+      0x00000000f20c0dfe,
+      // (x^95 mod G) * x^32
+      0x00000000493c7d27};
 
   // Medium runs of bytes are broken into groups of kGroupsSmall blocks of same
   // size. Each group is CRCed in parallel then combined at the end of the
diff --git a/absl/debugging/BUILD.bazel b/absl/debugging/BUILD.bazel
index 01d3230..cd0f1de 100644
--- a/absl/debugging/BUILD.bazel
+++ b/absl/debugging/BUILD.bazel
@@ -66,7 +66,9 @@
     linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":stacktrace",
+        "//absl/base:config",
         "//absl/base:core_headers",
+        "//absl/types:span",
         "@googletest//:gtest",
         "@googletest//:gtest_main",
     ],
diff --git a/absl/debugging/CMakeLists.txt b/absl/debugging/CMakeLists.txt
index 30eeb5b..60b138a 100644
--- a/absl/debugging/CMakeLists.txt
+++ b/absl/debugging/CMakeLists.txt
@@ -55,7 +55,9 @@
     ${ABSL_TEST_COPTS}
   DEPS
     absl::stacktrace
+    absl::config
     absl::core_headers
+    absl::span
     GTest::gmock_main
 )
 
diff --git a/absl/debugging/internal/addresses.h b/absl/debugging/internal/addresses.h
index e40c54e..504fd6f 100644
--- a/absl/debugging/internal/addresses.h
+++ b/absl/debugging/internal/addresses.h
@@ -25,14 +25,14 @@
 
 // Removes any metadata (tag bits) from the given pointer, converting it into a
 // user-readable address.
-inline uintptr_t StripPointerMetadata(void* ptr) {
+inline uintptr_t StripPointerMetadata(uintptr_t ptr) {
 #if defined(__aarch64__)
   // When PAC-RET (-mbranch-protection=pac-ret) is enabled, return addresses
   // stored on the stack will be signed, which means that pointer bits outside
   // of the virtual address range are potentially set. Since the stacktrace code
   // is expected to return normal code pointers, this function clears those
   // bits.
-  register uintptr_t x30 __asm__("x30") = reinterpret_cast<uintptr_t>(ptr);
+  register uintptr_t x30 __asm__("x30") = ptr;
   // The normal instruction for clearing PAC bits is XPACI, but for
   // compatibility with ARM platforms that do not support pointer
   // authentication, we use the hint space instruction XPACLRI instead. Hint
@@ -42,10 +42,14 @@
 #undef ABSL_XPACLRI_HINT
   return x30;
 #else
-  return reinterpret_cast<uintptr_t>(ptr);
+  return ptr;
 #endif
 }
 
+inline uintptr_t StripPointerMetadata(void* ptr) {
+  return StripPointerMetadata(reinterpret_cast<uintptr_t>(ptr));
+}
+
 }  // namespace debugging_internal
 ABSL_NAMESPACE_END
 }  // namespace absl
diff --git a/absl/debugging/internal/stacktrace_aarch64-inl.inc b/absl/debugging/internal/stacktrace_aarch64-inl.inc
index baea9a8..d1f67f1 100644
--- a/absl/debugging/internal/stacktrace_aarch64-inl.inc
+++ b/absl/debugging/internal/stacktrace_aarch64-inl.inc
@@ -185,8 +185,9 @@
 ABSL_ATTRIBUTE_NOINLINE
 ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS  // May read random elements from stack.
 ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY   // May read random elements from stack.
-static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count,
-                      const void *ucp, int *min_dropped_frames) {
+static int UnwindImpl(void **result, uintptr_t *frames, int *sizes,
+                      int max_depth, int skip_count, const void *ucp,
+                      int *min_dropped_frames) {
 #ifdef __GNUC__
   void **frame_pointer = reinterpret_cast<void**>(__builtin_frame_address(0));
 #else
@@ -223,8 +224,15 @@
       result[n] = reinterpret_cast<void *>(
           absl::debugging_internal::StripPointerMetadata(prev_return_address));
       if (IS_STACK_FRAMES) {
-        sizes[n] = static_cast<int>(
-            ComputeStackFrameSize(prev_frame_pointer, frame_pointer));
+        if (frames != nullptr) {
+          frames[n] = absl::debugging_internal::StripPointerMetadata(
+                          prev_frame_pointer) +
+                      2 * sizeof(void *) /* go past the return address */;
+        }
+        if (sizes != nullptr) {
+          sizes[n] = static_cast<int>(
+              ComputeStackFrameSize(prev_frame_pointer, frame_pointer));
+        }
       }
       n++;
     }
diff --git a/absl/debugging/internal/stacktrace_arm-inl.inc b/absl/debugging/internal/stacktrace_arm-inl.inc
index 102a2a1..3feb521 100644
--- a/absl/debugging/internal/stacktrace_arm-inl.inc
+++ b/absl/debugging/internal/stacktrace_arm-inl.inc
@@ -19,6 +19,7 @@
 
 #include <cstdint>
 
+#include "absl/debugging/internal/addresses.h"
 #include "absl/debugging/stacktrace.h"
 
 // WARNING:
@@ -67,8 +68,9 @@
 #endif
 
 template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT>
-static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count,
-                      const void * /* ucp */, int *min_dropped_frames) {
+static int UnwindImpl(void **result, uintptr_t *frames, int *sizes,
+                      int max_depth, int skip_count, const void * /* ucp */,
+                      int *min_dropped_frames) {
 #ifdef __GNUC__
   void **sp = reinterpret_cast<void**>(__builtin_frame_address(0));
 #else
@@ -97,11 +99,18 @@
       result[n] = *sp;
 
       if (IS_STACK_FRAMES) {
-        if (next_sp > sp) {
-          sizes[n] = (uintptr_t)next_sp - (uintptr_t)sp;
-        } else {
-          // A frame-size of 0 is used to indicate unknown frame size.
-          sizes[n] = 0;
+        if (frames != nullptr) {
+          frames[n] = absl::debugging_internal::StripPointerMetadata(sp) +
+                      1 * sizeof(void *) /* go past the return address */;
+        }
+        if (sizes != nullptr) {
+          if (next_sp > sp) {
+            sizes[n] = absl::debugging_internal::StripPointerMetadata(next_sp) -
+                       absl::debugging_internal::StripPointerMetadata(sp);
+          } else {
+            // A frame-size of 0 is used to indicate unknown frame size.
+            sizes[n] = 0;
+          }
         }
       }
       n++;
diff --git a/absl/debugging/internal/stacktrace_emscripten-inl.inc b/absl/debugging/internal/stacktrace_emscripten-inl.inc
index 0f44451..6689300 100644
--- a/absl/debugging/internal/stacktrace_emscripten-inl.inc
+++ b/absl/debugging/internal/stacktrace_emscripten-inl.inc
@@ -21,6 +21,7 @@
 #define ABSL_DEBUGGING_INTERNAL_STACKTRACE_EMSCRIPTEN_INL_H_
 
 #include <emscripten.h>
+#include <stdint.h>
 
 #include <atomic>
 #include <cstring>
@@ -62,8 +63,9 @@
 }();
 
 template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT>
-static int UnwindImpl(void **result, int *sizes, int max_depth, int skip_count,
-                      const void *ucp, int *min_dropped_frames) {
+static int UnwindImpl(void **result, uintptr_t *frames, int *sizes,
+                      int max_depth, int skip_count, const void *ucp,
+                      int *min_dropped_frames) {
   if (recursive || disable_stacktraces.load(std::memory_order_relaxed)) {
     return 0;
   }
@@ -83,8 +85,13 @@
   for (int i = 0; i < result_count; i++) result[i] = stack[i + skip_count];
 
   if (IS_STACK_FRAMES) {
-    // No implementation for finding out the stack frame sizes yet.
-    memset(sizes, 0, sizeof(*sizes) * result_count);
+    // No implementation for finding out the stack frames yet.
+    if (frames != nullptr) {
+      memset(frames, 0, sizeof(*frames) * result_count);
+    }
+    if (sizes != nullptr) {
+      memset(sizes, 0, sizeof(*sizes) * result_count);
+    }
   }
   if (min_dropped_frames != nullptr) {
     if (size - skip_count - max_depth > 0) {
diff --git a/absl/debugging/internal/stacktrace_generic-inl.inc b/absl/debugging/internal/stacktrace_generic-inl.inc
index 5fa169a..e7a11fc 100644
--- a/absl/debugging/internal/stacktrace_generic-inl.inc
+++ b/absl/debugging/internal/stacktrace_generic-inl.inc
@@ -56,8 +56,9 @@
 }();
 
 template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT>
-static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count,
-                      const void *ucp, int *min_dropped_frames) {
+static int UnwindImpl(void** result, uintptr_t* frames, int* sizes,
+                      int max_depth, int skip_count, const void* ucp,
+                      int* min_dropped_frames) {
   if (recursive || disable_stacktraces.load(std::memory_order_relaxed)) {
     return 0;
   }
@@ -79,8 +80,13 @@
     result[i] = stack[i + skip_count];
 
   if (IS_STACK_FRAMES) {
-    // No implementation for finding out the stack frame sizes yet.
-    memset(sizes, 0, sizeof(*sizes) * static_cast<size_t>(result_count));
+    // No implementation for finding out the stack frames yet.
+    if (frames != nullptr) {
+      memset(frames, 0, sizeof(*frames) * static_cast<size_t>(result_count));
+    }
+    if (sizes != nullptr) {
+      memset(sizes, 0, sizeof(*sizes) * static_cast<size_t>(result_count));
+    }
   }
   if (min_dropped_frames != nullptr) {
     if (size - skip_count - max_depth > 0) {
diff --git a/absl/debugging/internal/stacktrace_powerpc-inl.inc b/absl/debugging/internal/stacktrace_powerpc-inl.inc
index a49ed2f..b84782b 100644
--- a/absl/debugging/internal/stacktrace_powerpc-inl.inc
+++ b/absl/debugging/internal/stacktrace_powerpc-inl.inc
@@ -21,6 +21,7 @@
 #ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_POWERPC_INL_H_
 #define ABSL_DEBUGGING_INTERNAL_STACKTRACE_POWERPC_INL_H_
 
+#include "absl/debugging/internal/addresses.h"
 #if defined(__linux__)
 #include <asm/ptrace.h>   // for PT_NIP.
 #include <ucontext.h>     // for ucontext_t
@@ -40,22 +41,22 @@
 
 // Given a stack pointer, return the saved link register value.
 // Note that this is the link register for a callee.
-static inline void *StacktracePowerPCGetLR(void **sp) {
+static inline void **StacktracePowerPCGetLRPtr(void **sp) {
   // PowerPC has 3 main ABIs, which say where in the stack the
   // Link Register is.  For DARWIN and AIX (used by apple and
   // linux ppc64), it's in sp[2].  For SYSV (used by linux ppc),
   // it's in sp[1].
 #if defined(_CALL_AIX) || defined(_CALL_DARWIN)
-  return *(sp+2);
+  return (sp + 2);
 #elif defined(_CALL_SYSV)
-  return *(sp+1);
+  return (sp + 1);
 #elif defined(__APPLE__) || defined(__FreeBSD__) || \
     (defined(__linux__) && defined(__PPC64__))
   // This check is in case the compiler doesn't define _CALL_AIX/etc.
-  return *(sp+2);
+  return (sp + 2);
 #elif defined(__linux)
   // This check is in case the compiler doesn't define _CALL_SYSV.
-  return *(sp+1);
+  return (sp + 1);
 #else
 #error Need to specify the PPC ABI for your architecture.
 #endif
@@ -125,9 +126,8 @@
       }
     }
 
-    if (new_sp != nullptr &&
-        kernel_symbol_status == kAddressValid &&
-        StacktracePowerPCGetLR(new_sp) == kernel_sigtramp_rt64_address) {
+    if (new_sp != nullptr && kernel_symbol_status == kAddressValid &&
+        *StacktracePowerPCGetLRPtr(new_sp) == kernel_sigtramp_rt64_address) {
       const ucontext_t* signal_context =
           reinterpret_cast<const ucontext_t*>(uc);
       void **const sp_before_signal =
@@ -164,8 +164,9 @@
 template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT>
 ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS  // May read random elements from stack.
 ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY   // May read random elements from stack.
-static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count,
-                      const void *ucp, int *min_dropped_frames) {
+static int UnwindImpl(void **result, uintptr_t *frames, int *sizes,
+                      int max_depth, int skip_count, const void *ucp,
+                      int *min_dropped_frames) {
   void **sp;
   // Apple macOS uses an old version of gnu as -- both Darwin 7.9.0 (Panther)
   // and Darwin 8.8.1 (Tiger) use as 1.38.  This means we have to use a
@@ -211,13 +212,21 @@
     if (skip_count > 0) {
       skip_count--;
     } else {
-      result[n] = StacktracePowerPCGetLR(sp);
+      void **lr = StacktracePowerPCGetLRPtr(sp);
+      result[n] = *lr;
       if (IS_STACK_FRAMES) {
-        if (next_sp > sp) {
-          sizes[n] = (uintptr_t)next_sp - (uintptr_t)sp;
-        } else {
-          // A frame-size of 0 is used to indicate unknown frame size.
-          sizes[n] = 0;
+        if (frames != nullptr) {
+          frames[n] = absl::debugging_internal::StripPointerMetadata(lr) +
+                      1 * sizeof(void *) /* go past the return address */;
+        }
+        if (sizes != nullptr) {
+          if (next_sp > sp) {
+            sizes[n] = absl::debugging_internal::StripPointerMetadata(next_sp) -
+                       absl::debugging_internal::StripPointerMetadata(sp);
+          } else {
+            // A frame-size of 0 is used to indicate unknown frame size.
+            sizes[n] = 0;
+          }
         }
       }
       n++;
diff --git a/absl/debugging/internal/stacktrace_riscv-inl.inc b/absl/debugging/internal/stacktrace_riscv-inl.inc
index 3f9e124..59f2913 100644
--- a/absl/debugging/internal/stacktrace_riscv-inl.inc
+++ b/absl/debugging/internal/stacktrace_riscv-inl.inc
@@ -20,6 +20,7 @@
 #include <sys/ucontext.h>
 
 #include "absl/base/config.h"
+#include "absl/debugging/internal/addresses.h"
 #if defined(__linux__)
 #include <sys/mman.h>
 #include <ucontext.h>
@@ -117,8 +118,9 @@
 template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT>
 ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS  // May read random elements from stack.
 ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY   // May read random elements from stack.
-static int UnwindImpl(void **result, int *sizes, int max_depth, int skip_count,
-                      const void *ucp, int *min_dropped_frames) {
+static int UnwindImpl(void **result, uintptr_t *frames, int *sizes,
+                      int max_depth, int skip_count, const void *ucp,
+                      int *min_dropped_frames) {
   // The `frame_pointer` that is computed here points to the top of the frame.
   // The two words preceding the address are the return address and the previous
   // frame pointer.
@@ -153,8 +155,13 @@
       result[n] = return_address;
       if (IS_STACK_FRAMES) {
         // NextStackFrame() has already checked that frame size fits to int
-        sizes[n] = static_cast<int>(ComputeStackFrameSize(frame_pointer,
-                                                          next_frame_pointer));
+        if (frames != nullptr) {
+          frames[n] =
+              absl::debugging_internal::StripPointerMetadata(frame_pointer);
+        }
+        if (sizes != nullptr) {
+          sizes[n] = ComputeStackFrameSize(frame_pointer, next_frame_pointer);
+        }
       }
       n++;
     }
diff --git a/absl/debugging/internal/stacktrace_unimplemented-inl.inc b/absl/debugging/internal/stacktrace_unimplemented-inl.inc
index 5b8fb19..ec63940 100644
--- a/absl/debugging/internal/stacktrace_unimplemented-inl.inc
+++ b/absl/debugging/internal/stacktrace_unimplemented-inl.inc
@@ -2,9 +2,10 @@
 #define ABSL_DEBUGGING_INTERNAL_STACKTRACE_UNIMPLEMENTED_INL_H_
 
 template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT>
-static int UnwindImpl(void** /* result */, int* /* sizes */,
-                      int /* max_depth */, int /* skip_count */,
-                      const void* /* ucp */, int *min_dropped_frames) {
+static int UnwindImpl(void** /* result */, uintptr_t* /* frames */,
+                      int* /* sizes */, int /* max_depth */,
+                      int /* skip_count */, const void* /* ucp */,
+                      int* min_dropped_frames) {
   if (min_dropped_frames != nullptr) {
     *min_dropped_frames = 0;
   }
diff --git a/absl/debugging/internal/stacktrace_win32-inl.inc b/absl/debugging/internal/stacktrace_win32-inl.inc
index ef2b973..513a392 100644
--- a/absl/debugging/internal/stacktrace_win32-inl.inc
+++ b/absl/debugging/internal/stacktrace_win32-inl.inc
@@ -61,8 +61,9 @@
 #endif  // WINAPI_PARTITION_APP && !WINAPI_PARTITION_DESKTOP
 
 template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT>
-static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count,
-                      const void*, int* min_dropped_frames) {
+static int UnwindImpl(void** result, uintptr_t* frames, int* sizes,
+                      int max_depth, int skip_count, const void*,
+                      int* min_dropped_frames) {
   USHORT n = 0;
   if (!RtlCaptureStackBackTrace_fn || skip_count < 0 || max_depth < 0) {
     // can't get a stacktrace with no function/invalid args
@@ -71,8 +72,13 @@
                                     static_cast<ULONG>(max_depth), result, 0);
   }
   if (IS_STACK_FRAMES) {
-    // No implementation for finding out the stack frame sizes yet.
-    memset(sizes, 0, sizeof(*sizes) * n);
+    // No implementation for finding out the stack frames yet.
+    if (frames != nullptr) {
+      memset(frames, 0, sizeof(*frames) * n);
+    }
+    if (sizes != nullptr) {
+      memset(sizes, 0, sizeof(*sizes) * n);
+    }
   }
   if (min_dropped_frames != nullptr) {
     // Not implemented.
diff --git a/absl/debugging/internal/stacktrace_x86-inl.inc b/absl/debugging/internal/stacktrace_x86-inl.inc
index 1975ba7..2662dab 100644
--- a/absl/debugging/internal/stacktrace_x86-inl.inc
+++ b/absl/debugging/internal/stacktrace_x86-inl.inc
@@ -33,6 +33,7 @@
 #include "absl/base/macros.h"
 #include "absl/base/port.h"
 #include "absl/debugging/internal/address_is_readable.h"
+#include "absl/debugging/internal/addresses.h"
 #include "absl/debugging/internal/vdso_support.h"  // a no-op on non-elf or non-glibc systems
 #include "absl/debugging/stacktrace.h"
 
@@ -327,8 +328,9 @@
 ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS  // May read random elements from stack.
 ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY   // May read random elements from stack.
 ABSL_ATTRIBUTE_NOINLINE
-static int UnwindImpl(void **result, int *sizes, int max_depth, int skip_count,
-                      const void *ucp, int *min_dropped_frames) {
+static int UnwindImpl(void **result, uintptr_t *frames, int *sizes,
+                      int max_depth, int skip_count, const void *ucp,
+                      int *min_dropped_frames) {
   int n = 0;
   void **fp = reinterpret_cast<void **>(__builtin_frame_address(0));
 
@@ -349,13 +351,19 @@
     } else {
       result[n] = *(fp + 1);
       if (IS_STACK_FRAMES) {
-        if (next_fp > fp) {
-          sizes[n] = static_cast<int>(
-              reinterpret_cast<uintptr_t>(next_fp) -
-              reinterpret_cast<uintptr_t>(fp));
-        } else {
-          // A frame-size of 0 is used to indicate unknown frame size.
-          sizes[n] = 0;
+        if (frames) {
+          frames[n] = absl::debugging_internal::StripPointerMetadata(fp) +
+                      2 * sizeof(void *) /* go past the return address */;
+        }
+        if (sizes) {
+          if (next_fp > fp) {
+            sizes[n] = static_cast<int>(
+                absl::debugging_internal::StripPointerMetadata(next_fp) -
+                absl::debugging_internal::StripPointerMetadata(fp));
+          } else {
+            // A frame-size of 0 is used to indicate unknown frame size.
+            sizes[n] = 0;
+          }
         }
       }
       n++;
diff --git a/absl/debugging/stacktrace.cc b/absl/debugging/stacktrace.cc
index ff8069f..d8ad0e6 100644
--- a/absl/debugging/stacktrace.cc
+++ b/absl/debugging/stacktrace.cc
@@ -36,9 +36,14 @@
 
 #include "absl/debugging/stacktrace.h"
 
+#include <stdint.h>
+
+#include <algorithm>
 #include <atomic>
 
 #include "absl/base/attributes.h"
+#include "absl/base/config.h"
+#include "absl/base/optimization.h"
 #include "absl/base/port.h"
 #include "absl/debugging/internal/stacktrace_config.h"
 
@@ -66,59 +71,68 @@
 std::atomic<Unwinder> custom;
 
 template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT>
-ABSL_ATTRIBUTE_ALWAYS_INLINE inline int Unwind(void** result, int* sizes,
-                                               int max_depth, int skip_count,
-                                               const void* uc,
+ABSL_ATTRIBUTE_ALWAYS_INLINE inline int Unwind(void** result, uintptr_t* frames,
+                                               int* sizes, int max_depth,
+                                               int skip_count, const void* uc,
                                                int* min_dropped_frames) {
-  Unwinder f = &UnwindImpl<IS_STACK_FRAMES, IS_WITH_CONTEXT>;
   Unwinder g = custom.load(std::memory_order_acquire);
-  if (g != nullptr) f = g;
-
+  int size;
   // Add 1 to skip count for the unwinder function itself
-  int size = (*f)(result, sizes, max_depth, skip_count + 1, uc,
-                  min_dropped_frames);
-  // To disable tail call to (*f)(...)
+  ++skip_count;
+  if (g != nullptr) {
+    size = (*g)(result, sizes, max_depth, skip_count, uc, min_dropped_frames);
+    // Frame pointers aren't returned by existing hooks, so clear them.
+    if (frames != nullptr) {
+      std::fill(frames, frames + size, uintptr_t());
+    }
+  } else {
+    size = UnwindImpl<IS_STACK_FRAMES, IS_WITH_CONTEXT>(
+        result, frames, sizes, max_depth, skip_count, uc, min_dropped_frames);
+  }
   ABSL_BLOCK_TAIL_CALL_OPTIMIZATION();
   return size;
 }
 
 }  // anonymous namespace
 
-ABSL_ATTRIBUTE_NOINLINE ABSL_ATTRIBUTE_NO_TAIL_CALL int GetStackFrames(
-    void** result, int* sizes, int max_depth, int skip_count) {
-  return Unwind<true, false>(result, sizes, max_depth, skip_count, nullptr,
-                             nullptr);
+ABSL_ATTRIBUTE_NOINLINE ABSL_ATTRIBUTE_NO_TAIL_CALL int
+internal_stacktrace::GetStackFrames(void** result, uintptr_t* frames,
+                                    int* sizes, int max_depth, int skip_count) {
+  return Unwind<true, false>(result, frames, sizes, max_depth, skip_count,
+                             nullptr, nullptr);
 }
 
 ABSL_ATTRIBUTE_NOINLINE ABSL_ATTRIBUTE_NO_TAIL_CALL int
-GetStackFramesWithContext(void** result, int* sizes, int max_depth,
-                          int skip_count, const void* uc,
-                          int* min_dropped_frames) {
-  return Unwind<true, true>(result, sizes, max_depth, skip_count, uc,
+internal_stacktrace::GetStackFramesWithContext(void** result, uintptr_t* frames,
+                                               int* sizes, int max_depth,
+                                               int skip_count, const void* uc,
+                                               int* min_dropped_frames) {
+  return Unwind<true, true>(result, frames, sizes, max_depth, skip_count, uc,
                             min_dropped_frames);
 }
 
 ABSL_ATTRIBUTE_NOINLINE ABSL_ATTRIBUTE_NO_TAIL_CALL int GetStackTrace(
     void** result, int max_depth, int skip_count) {
-  return Unwind<false, false>(result, nullptr, max_depth, skip_count, nullptr,
-                              nullptr);
+  return Unwind<false, false>(result, nullptr, nullptr, max_depth, skip_count,
+                              nullptr, nullptr);
 }
 
 ABSL_ATTRIBUTE_NOINLINE ABSL_ATTRIBUTE_NO_TAIL_CALL int
 GetStackTraceWithContext(void** result, int max_depth, int skip_count,
                          const void* uc, int* min_dropped_frames) {
-  return Unwind<false, true>(result, nullptr, max_depth, skip_count, uc,
-                             min_dropped_frames);
+  return Unwind<false, true>(result, nullptr, nullptr, max_depth, skip_count,
+                             uc, min_dropped_frames);
 }
 
 void SetStackUnwinder(Unwinder w) {
   custom.store(w, std::memory_order_release);
 }
 
-int DefaultStackUnwinder(void** pcs, int* sizes, int depth, int skip,
-                         const void* uc, int* min_dropped_frames) {
+ABSL_ATTRIBUTE_ALWAYS_INLINE static inline int DefaultStackUnwinderImpl(
+    void** pcs, uintptr_t* frames, int* sizes, int depth, int skip,
+    const void* uc, int* min_dropped_frames) {
   skip++;  // For this function
-  Unwinder f = nullptr;
+  decltype(&UnwindImpl<false, false>) f;
   if (sizes == nullptr) {
     if (uc == nullptr) {
       f = &UnwindImpl<false, false>;
@@ -132,9 +146,26 @@
       f = &UnwindImpl<true, true>;
     }
   }
-  volatile int x = 0;
-  int n = (*f)(pcs, sizes, depth, skip, uc, min_dropped_frames);
-  x = 1; (void) x;  // To disable tail call to (*f)(...)
+  return (*f)(pcs, frames, sizes, depth, skip, uc, min_dropped_frames);
+}
+
+ABSL_ATTRIBUTE_NOINLINE ABSL_ATTRIBUTE_NO_TAIL_CALL int
+internal_stacktrace::DefaultStackUnwinder(void** pcs, uintptr_t* frames,
+                                          int* sizes, int depth, int skip,
+                                          const void* uc,
+                                          int* min_dropped_frames) {
+  int n = DefaultStackUnwinderImpl(pcs, frames, sizes, depth, skip, uc,
+                                   min_dropped_frames);
+  ABSL_BLOCK_TAIL_CALL_OPTIMIZATION();
+  return n;
+}
+
+ABSL_ATTRIBUTE_NOINLINE ABSL_ATTRIBUTE_NO_TAIL_CALL int DefaultStackUnwinder(
+    void** pcs, int* sizes, int depth, int skip, const void* uc,
+    int* min_dropped_frames) {
+  int n = DefaultStackUnwinderImpl(pcs, nullptr, sizes, depth, skip, uc,
+                                   min_dropped_frames);
+  ABSL_BLOCK_TAIL_CALL_OPTIMIZATION();
   return n;
 }
 
diff --git a/absl/debugging/stacktrace.h b/absl/debugging/stacktrace.h
index 0ec0ffd..b55babb 100644
--- a/absl/debugging/stacktrace.h
+++ b/absl/debugging/stacktrace.h
@@ -31,11 +31,52 @@
 #ifndef ABSL_DEBUGGING_STACKTRACE_H_
 #define ABSL_DEBUGGING_STACKTRACE_H_
 
+#include <stdint.h>
+
+#include "absl/base/attributes.h"
 #include "absl/base/config.h"
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
 
+namespace internal_stacktrace {
+
+// Same as `absl::GetStackFrames`, but with an optional `frames` parameter to
+// allow callers to receive the raw stack frame addresses.
+// This is internal for now; use `absl::GetStackFrames()` instead.
+extern int GetStackFrames(void** result, uintptr_t* frames, int* sizes,
+                          int max_depth, int skip_count);
+
+// Same as `absl::GetStackFramesWithContext`, but with an optional `frames`
+// parameter to allow callers to receive a start address for each stack frame.
+// The address may be zero in cases where it cannot be computed.
+//
+// DO NOT use this function without consulting the owners of absl/debuggging.
+// There is NO GUARANTEE on the precise frame addresses returned on any given
+// platform. It is only intended to provide sufficient non-overlapping bounds on
+// the local variables of a stack frame when used in conjunction with the
+// returned frame sizes. The actual pointers may be ABI-dependent, may vary at
+// run time, and are subject to breakage without notice.
+//
+// Implementation note:
+// Currently, we *attempt* to return the Canonical Frame Address (CFA) in DWARF
+// on most platforms. This is the value of the stack pointer just before the
+// 'call' instruction is executed in the caller.
+// Not all platforms and toolchains support this exact address, so this should
+// not be relied on for correctness.
+extern int GetStackFramesWithContext(void** result, uintptr_t* frames,
+                                     int* sizes, int max_depth, int skip_count,
+                                     const void* uc, int* min_dropped_frames);
+
+// Same as `absl::DefaultStackUnwinder`, but with an optional `frames` parameter
+// to allow callers to receive the raw stack frame addresses.
+// This is internal for now; do not depend on this externally.
+extern int DefaultStackUnwinder(void** pcs, uintptr_t* frames, int* sizes,
+                                int max_depth, int skip_count, const void* uc,
+                                int* min_dropped_frames);
+
+}  // namespace internal_stacktrace
+
 // GetStackFrames()
 //
 // Records program counter values for up to `max_depth` frames, skipping the
@@ -78,8 +119,13 @@
 //
 // This routine may return fewer stack frame entries than are
 // available. Also note that `result` and `sizes` must both be non-null.
-extern int GetStackFrames(void** result, int* sizes, int max_depth,
-                          int skip_count);
+ABSL_ATTRIBUTE_ALWAYS_INLINE inline int GetStackFrames(void** result,
+                                                       int* sizes,
+                                                       int max_depth,
+                                                       int skip_count) {
+  return internal_stacktrace::GetStackFrames(result, nullptr, sizes, max_depth,
+                                             skip_count);
+}
 
 // GetStackFramesWithContext()
 //
@@ -102,9 +148,12 @@
 // or other reasons. (This value will be set to `0` if no frames were dropped.)
 // The number of total stack frames is guaranteed to be >= skip_count +
 // max_depth + *min_dropped_frames.
-extern int GetStackFramesWithContext(void** result, int* sizes, int max_depth,
-                                     int skip_count, const void* uc,
-                                     int* min_dropped_frames);
+ABSL_ATTRIBUTE_ALWAYS_INLINE inline int GetStackFramesWithContext(
+    void** result, int* sizes, int max_depth, int skip_count, const void* uc,
+    int* min_dropped_frames) {
+  return internal_stacktrace::GetStackFramesWithContext(
+      result, nullptr, sizes, max_depth, skip_count, uc, min_dropped_frames);
+}
 
 // GetStackTrace()
 //
diff --git a/absl/debugging/stacktrace_test.cc b/absl/debugging/stacktrace_test.cc
index 31f7723..f31f624 100644
--- a/absl/debugging/stacktrace_test.cc
+++ b/absl/debugging/stacktrace_test.cc
@@ -14,12 +14,30 @@
 
 #include "absl/debugging/stacktrace.h"
 
+#include <stddef.h>
+#include <stdint.h>
+
+#include <algorithm>
+
+#include "gmock/gmock.h"
 #include "gtest/gtest.h"
-#include "absl/base/macros.h"
+#include "absl/base/attributes.h"
+#include "absl/base/config.h"
 #include "absl/base/optimization.h"
+#include "absl/types/span.h"
 
 namespace {
 
+using ::testing::Contains;
+
+struct StackTrace {
+  static constexpr int kStackCount = 64;
+  int depth;
+  void* result[kStackCount];
+  uintptr_t frames[kStackCount];
+  int sizes[kStackCount];
+};
+
 // This test is currently only known to pass on Linux x86_64/aarch64.
 #if defined(__linux__) && (defined(__x86_64__) || defined(__aarch64__))
 ABSL_ATTRIBUTE_NOINLINE void Unwind(void* p) {
@@ -44,4 +62,84 @@
 }
 #endif
 
+#if ABSL_HAVE_BUILTIN(__builtin_frame_address)
+struct FrameInfo {
+  const void* return_address;
+  uintptr_t frame_address;
+};
+
+// Returns the canonical frame address and return address for the current stack
+// frame, while capturing the stack trace at the same time.
+// This performs any platform-specific adjustments necessary to convert from the
+// compiler built-ins to the expected API outputs.
+ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS     // May read random elements from stack.
+    ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY  // May read random elements from stack.
+        ABSL_ATTRIBUTE_NOINLINE static FrameInfo
+        CaptureBacktraceNoInline(StackTrace& backtrace) {
+  FrameInfo result;
+  result.return_address = __builtin_return_address(0);
+  // Large enough to cover all realistic slots the return address could be in
+  const int kMaxReturnAddressIndex = 5;
+  void* const* bfa = static_cast<void* const*>(__builtin_frame_address(0));
+  backtrace.depth = absl::internal_stacktrace::GetStackFramesWithContext(
+      backtrace.result, backtrace.frames, backtrace.sizes,
+      StackTrace::kStackCount, /*skip_count=*/0,
+      /*uc=*/nullptr, /*min_dropped_frames=*/nullptr);
+  // Make sure the return address is at a reasonable location in the frame
+  ptrdiff_t i;
+  for (i = 0; i < kMaxReturnAddressIndex; ++i) {
+    // Avoid std::find() here, since it lacks no-sanitize attributes.
+    if (bfa[i] == result.return_address) {
+      break;
+    }
+  }
+  result.frame_address =
+      i < kMaxReturnAddressIndex
+          ? reinterpret_cast<uintptr_t>(
+                bfa + i + 1 /* get the Canonical Frame Address (CFA) */)
+          : 0;
+  return result;
+}
+
+TEST(StackTrace, CanonicalFrameAddresses) {
+  // Now capture a stack trace and verify that the return addresses and frame
+  // addresses line up for one frame.
+  StackTrace backtrace;
+  const auto [return_address, frame_address] =
+      CaptureBacktraceNoInline(backtrace);
+  auto return_addresses = absl::MakeSpan(backtrace.result)
+                              .subspan(0, static_cast<size_t>(backtrace.depth));
+  auto frame_addresses = absl::MakeSpan(backtrace.frames)
+                             .subspan(0, static_cast<size_t>(backtrace.depth));
+
+  // Many platforms don't support this by default.
+  bool support_is_expected = false;
+
+  if (support_is_expected) {
+    // If all zeros were returned, that is valid per the function's contract.
+    // It just means we don't support returning frame addresses on this
+    // platform.
+    bool supported = static_cast<size_t>(std::count(frame_addresses.begin(),
+                                                    frame_addresses.end(), 0)) <
+                     frame_addresses.size();
+    EXPECT_TRUE(supported);
+    if (supported) {
+      ASSERT_TRUE(frame_address)
+          << "unable to obtain frame address corresponding to return address";
+      EXPECT_THAT(return_addresses, Contains(return_address).Times(1));
+      EXPECT_THAT(frame_addresses, Contains(frame_address).Times(1));
+      ptrdiff_t ifound = std::find(return_addresses.begin(),
+                                   return_addresses.end(), return_address) -
+                         return_addresses.begin();
+      // Make sure we found the frame in the first place.
+      ASSERT_LT(ifound, backtrace.depth);
+      // Make sure the frame address actually corresponds to the return
+      // address.
+      EXPECT_EQ(frame_addresses[static_cast<size_t>(ifound)], frame_address);
+      // Make sure the addresses only appear once.
+    }
+  }
+}
+#endif
+
 }  // namespace
diff --git a/absl/flags/BUILD.bazel b/absl/flags/BUILD.bazel
index d9a3034..5e9bec4 100644
--- a/absl/flags/BUILD.bazel
+++ b/absl/flags/BUILD.bazel
@@ -245,6 +245,7 @@
         ":reflection",
         "//absl/base:config",
         "//absl/base:core_headers",
+        "//absl/base:nullability",
         "//absl/strings",
     ],
 )
diff --git a/absl/flags/CMakeLists.txt b/absl/flags/CMakeLists.txt
index 5430429..f995957 100644
--- a/absl/flags/CMakeLists.txt
+++ b/absl/flags/CMakeLists.txt
@@ -218,6 +218,7 @@
     absl::flags_internal
     absl::flags_reflection
     absl::core_headers
+    absl::nullability
     absl::strings
 )
 
diff --git a/absl/flags/flag.h b/absl/flags/flag.h
index 81b47ee..e052d5f 100644
--- a/absl/flags/flag.h
+++ b/absl/flags/flag.h
@@ -35,6 +35,7 @@
 
 #include "absl/base/attributes.h"
 #include "absl/base/config.h"
+#include "absl/base/nullability.h"
 #include "absl/base/optimization.h"
 #include "absl/flags/commandlineflag.h"
 #include "absl/flags/config.h"
@@ -106,7 +107,7 @@
 // thread-safe, but is potentially expensive. Avoid setting flags in general,
 // but especially within performance-critical code.
 template <typename T>
-void SetFlag(absl::Flag<T>* flag, const T& v) {
+void SetFlag(absl::Flag<T>* absl_nonnull flag, const T& v) {
   flags_internal::FlagImplPeer::InvokeSet(*flag, v);
 }
 
@@ -114,7 +115,7 @@
 // convertible to `T`. E.g., use this overload to pass a "const char*" when `T`
 // is `std::string`.
 template <typename T, typename V>
-void SetFlag(absl::Flag<T>* flag, const V& v) {
+void SetFlag(absl::Flag<T>* absl_nonnull flag, const V& v) {
   T value(v);
   flags_internal::FlagImplPeer::InvokeSet(*flag, value);
 }
diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h
index a243b79..ef739e7 100644
--- a/absl/flags/internal/flag.h
+++ b/absl/flags/internal/flag.h
@@ -783,7 +783,7 @@
   // heap allocation during initialization, which is both slows program startup
   // and can fail. Using reserved space + placement new allows us to avoid both
   // problems.
-  alignas(absl::Mutex) mutable char data_guard_[sizeof(absl::Mutex)];
+  alignas(absl::Mutex) mutable unsigned char data_guard_[sizeof(absl::Mutex)];
 };
 #if defined(__GNUC__) && !defined(__clang__)
 #pragma GCC diagnostic pop
@@ -876,7 +876,8 @@
 template <typename T>
 void* FlagOps(FlagOp op, const void* v1, void* v2, void* v3) {
   struct AlignedSpace {
-    alignas(MaskedPointer::RequiredAlignment()) alignas(T) char buf[sizeof(T)];
+    alignas(MaskedPointer::RequiredAlignment()) alignas(
+        T) unsigned char buf[sizeof(T)];
   };
   using Allocator = std::allocator<AlignedSpace>;
   switch (op) {
diff --git a/absl/flags/internal/registry.h b/absl/flags/internal/registry.h
index 4b68c85..a57ba3c 100644
--- a/absl/flags/internal/registry.h
+++ b/absl/flags/internal/registry.h
@@ -73,7 +73,7 @@
 //
 
 // Retire flag with name "name" and type indicated by ops.
-void Retire(const char* name, FlagFastTypeId type_id, char* buf);
+void Retire(const char* name, FlagFastTypeId type_id, unsigned char* buf);
 
 constexpr size_t kRetiredFlagObjSize = 3 * sizeof(void*);
 constexpr size_t kRetiredFlagObjAlignment = alignof(void*);
@@ -87,7 +87,7 @@
   }
 
  private:
-  alignas(kRetiredFlagObjAlignment) char buf_[kRetiredFlagObjSize];
+  alignas(kRetiredFlagObjAlignment) unsigned char buf_[kRetiredFlagObjSize];
 };
 
 }  // namespace flags_internal
diff --git a/absl/flags/reflection.cc b/absl/flags/reflection.cc
index ea856ff..b8b4a2e 100644
--- a/absl/flags/reflection.cc
+++ b/absl/flags/reflection.cc
@@ -289,11 +289,10 @@
 
 }  // namespace
 
-void Retire(const char* name, FlagFastTypeId type_id, char* buf) {
+void Retire(const char* name, FlagFastTypeId type_id, unsigned char* buf) {
   static_assert(sizeof(RetiredFlagObj) == kRetiredFlagObjSize, "");
   static_assert(alignof(RetiredFlagObj) == kRetiredFlagObjAlignment, "");
-  auto* flag = ::new (static_cast<void*>(buf))
-      flags_internal::RetiredFlagObj(name, type_id);
+  auto* flag = ::new (buf) flags_internal::RetiredFlagObj(name, type_id);
   FlagRegistry::GlobalRegistry().RegisterFlag(*flag, nullptr);
 }
 
diff --git a/absl/functional/BUILD.bazel b/absl/functional/BUILD.bazel
index 8296f14..aeed3b6 100644
--- a/absl/functional/BUILD.bazel
+++ b/absl/functional/BUILD.bazel
@@ -146,8 +146,9 @@
     ],
 )
 
-cc_test(
+cc_binary(
     name = "function_type_benchmark",
+    testonly = True,
     srcs = [
         "function_type_benchmark.cc",
     ],
@@ -159,6 +160,5 @@
         ":function_ref",
         "//absl/base:core_headers",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
diff --git a/absl/functional/function_type_benchmark.cc b/absl/functional/function_type_benchmark.cc
index 03dc31d..513233b 100644
--- a/absl/functional/function_type_benchmark.cc
+++ b/absl/functional/function_type_benchmark.cc
@@ -16,10 +16,10 @@
 #include <memory>
 #include <string>
 
-#include "benchmark/benchmark.h"
 #include "absl/base/attributes.h"
 #include "absl/functional/any_invocable.h"
 #include "absl/functional/function_ref.h"
+#include "benchmark/benchmark.h"
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
diff --git a/absl/functional/internal/any_invocable.h b/absl/functional/internal/any_invocable.h
index 6bfc4d1..167d947 100644
--- a/absl/functional/internal/any_invocable.h
+++ b/absl/functional/internal/any_invocable.h
@@ -174,7 +174,7 @@
   } remote;
 
   // Local-storage for the type-erased object when small and trivial enough
-  alignas(kAlignment) char storage[kStorageSize];
+  alignas(kAlignment) unsigned char storage[kStorageSize];
 };
 
 // A typed accessor for the object in `TypeErasedState` storage
diff --git a/absl/log/CMakeLists.txt b/absl/log/CMakeLists.txt
index 949d442..6aae05d 100644
--- a/absl/log/CMakeLists.txt
+++ b/absl/log/CMakeLists.txt
@@ -747,6 +747,7 @@
     absl::log_internal_fnmatch
     absl::memory
     absl::no_destructor
+    absl::nullability
     absl::strings
     absl::synchronization
     absl::optional
diff --git a/absl/log/internal/BUILD.bazel b/absl/log/internal/BUILD.bazel
index d3f4a8f..5d54b6f 100644
--- a/absl/log/internal/BUILD.bazel
+++ b/absl/log/internal/BUILD.bazel
@@ -462,11 +462,12 @@
         "//absl/log:__subpackages__",
     ],
     deps = [
+        ":fnmatch",
         "//absl/base",
         "//absl/base:config",
         "//absl/base:core_headers",
         "//absl/base:no_destructor",
-        "//absl/log/internal:fnmatch",
+        "//absl/base:nullability",
         "//absl/memory",
         "//absl/strings",
         "//absl/synchronization",
diff --git a/absl/log/internal/conditions.h b/absl/log/internal/conditions.h
index 97edf65..6fb74b1 100644
--- a/absl/log/internal/conditions.h
+++ b/absl/log/internal/conditions.h
@@ -118,6 +118,8 @@
   ABSL_LOG_INTERNAL_##type##_CONDITION(                    \
       (condition) && ::absl::LogSeverity::kError >=        \
                          static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL))
+#define ABSL_LOG_INTERNAL_CONDITION_DO_NOT_SUBMIT(type, condition) \
+  ABSL_LOG_INTERNAL_CONDITION_ERROR(type, condition)
 // NOTE: Use ternary operators instead of short-circuiting to mitigate
 // https://bugs.llvm.org/show_bug.cgi?id=51928.
 #define ABSL_LOG_INTERNAL_CONDITION_FATAL(type, condition)                 \
@@ -169,6 +171,8 @@
   ABSL_LOG_INTERNAL_##type##_CONDITION(condition)
 #define ABSL_LOG_INTERNAL_CONDITION_ERROR(type, condition) \
   ABSL_LOG_INTERNAL_##type##_CONDITION(condition)
+#define ABSL_LOG_INTERNAL_CONDITION_DO_NOT_SUBMIT(type, condition) \
+  ABSL_LOG_INTERNAL_CONDITION_ERROR(type, condition)
 #define ABSL_LOG_INTERNAL_CONDITION_FATAL(type, condition) \
   ABSL_LOG_INTERNAL_##type##_CONDITION(condition)
 #define ABSL_LOG_INTERNAL_CONDITION_QFATAL(type, condition) \
diff --git a/absl/log/internal/fnmatch_test.cc b/absl/log/internal/fnmatch_test.cc
index e16a64e..614c7d3 100644
--- a/absl/log/internal/fnmatch_test.cc
+++ b/absl/log/internal/fnmatch_test.cc
@@ -27,6 +27,7 @@
   EXPECT_THAT(FNMatch("foo", "bar"), IsFalse());
   EXPECT_THAT(FNMatch("foo", "fo"), IsFalse());
   EXPECT_THAT(FNMatch("foo", "foo2"), IsFalse());
+  EXPECT_THAT(FNMatch("foo/*", "foo/1/2/3/4"), IsTrue());
   EXPECT_THAT(FNMatch("bar/foo.ext", "bar/foo.ext"), IsTrue());
   EXPECT_THAT(FNMatch("*ba*r/fo*o.ext*", "bar/foo.ext"), IsTrue());
   EXPECT_THAT(FNMatch("bar/foo.ext", "bar/baz.ext"), IsFalse());
diff --git a/absl/log/internal/strip.h b/absl/log/internal/strip.h
index 4846427..60ef878 100644
--- a/absl/log/internal/strip.h
+++ b/absl/log/internal/strip.h
@@ -15,7 +15,8 @@
 // -----------------------------------------------------------------------------
 // File: log/internal/strip.h
 // -----------------------------------------------------------------------------
-//
+
+// SKIP_ABSL_INLINE_NAMESPACE_CHECK
 
 #ifndef ABSL_LOG_INTERNAL_STRIP_H_
 #define ABSL_LOG_INTERNAL_STRIP_H_
@@ -94,4 +95,6 @@
 #define ABSL_LOGGING_INTERNAL_DLOG_DFATAL ABSL_LOGGING_INTERNAL_LOG_DFATAL
 #define ABSL_LOGGING_INTERNAL_DLOG_LEVEL ABSL_LOGGING_INTERNAL_LOG_LEVEL
 
+#define ABSL_LOGGING_INTERNAL_LOG_DO_NOT_SUBMIT ABSL_LOGGING_INTERNAL_LOG_ERROR
+
 #endif  // ABSL_LOG_INTERNAL_STRIP_H_
diff --git a/absl/log/internal/vlog_config.h b/absl/log/internal/vlog_config.h
index b6e322c..c6543a2 100644
--- a/absl/log/internal/vlog_config.h
+++ b/absl/log/internal/vlog_config.h
@@ -34,6 +34,7 @@
 
 #include "absl/base/attributes.h"
 #include "absl/base/config.h"
+#include "absl/base/nullability.h"
 #include "absl/base/optimization.h"
 #include "absl/base/thread_annotations.h"
 #include "absl/strings/string_view.h"
@@ -60,7 +61,7 @@
 class VLogSite final {
  public:
   // `f` must not be destroyed until the program exits.
-  explicit constexpr VLogSite(const char* f)
+  explicit constexpr VLogSite(const char* absl_nonnull f)
       : file_(f), v_(kUninitialized), next_(nullptr) {}
   VLogSite(const VLogSite&) = delete;
   VLogSite& operator=(const VLogSite&) = delete;
@@ -116,7 +117,7 @@
   ABSL_ATTRIBUTE_NOINLINE bool SlowIsEnabled5(int stale_v);
 
   // This object is too size-sensitive to use absl::string_view.
-  const char* const file_;
+  const char* absl_nonnull const file_;
   std::atomic<int> v_;
   std::atomic<VLogSite*> next_;
 };
diff --git a/absl/log/log.h b/absl/log/log.h
index 4a4e038..f1cab9d 100644
--- a/absl/log/log.h
+++ b/absl/log/log.h
@@ -34,6 +34,13 @@
 //   running registered error handlers.
 // * The `DFATAL` pseudo-severity level is defined as `FATAL` in debug mode and
 //   as `ERROR` otherwise.
+// * The `DO_NOT_SUBMIT` pseudo-severity level is an alias for `ERROR`, and is
+//   intended for debugging statements that won't be submitted.  The name is
+//   chosen to be easy to spot in review and with tools in order to ensure that
+//   such statements aren't inadvertently checked in.
+//   The contract is that **it may not be checked in**, meaning that no
+//   in-contract uses will be affected if we decide in the future to remove it
+//   or change what it does.
 // Some preprocessor shenanigans are used to ensure that e.g. `LOG(INFO)` has
 // the same meaning even if a local symbol or preprocessor macro named `INFO` is
 // defined.  To specify a severity level using an expression instead of a
@@ -194,6 +201,8 @@
 //   LOG(INFO) << std::hex << 0xdeadbeef;  // logs "0xdeadbeef"
 //   LOG(INFO) << 0xdeadbeef;              // logs "3735928559"
 
+// SKIP_ABSL_INLINE_NAMESPACE_CHECK
+
 #ifndef ABSL_LOG_LOG_H_
 #define ABSL_LOG_LOG_H_
 
diff --git a/absl/log/log_basic_test_impl.inc b/absl/log/log_basic_test_impl.inc
index 2c84b45..c4b4e24 100644
--- a/absl/log/log_basic_test_impl.inc
+++ b/absl/log/log_basic_test_impl.inc
@@ -13,6 +13,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+// SKIP_ABSL_INLINE_NAMESPACE_CHECK
+
 // The testcases in this file are expected to pass or be skipped with any value
 // of ABSL_MIN_LOG_LEVEL
 
@@ -181,6 +183,37 @@
   do_log();
 }
 
+TEST_P(BasicLogTest, DoNotSubmit) {
+  absl::log_internal::ScopedMinLogLevel scoped_min_log_level(GetParam());
+
+  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
+
+  const int log_line = __LINE__ + 1;
+  auto do_log = [] { ABSL_TEST_LOG(DO_NOT_SUBMIT) << "hello world"; };
+
+  if (LoggingEnabledAt(absl::LogSeverity::kError)) {
+    EXPECT_CALL(
+        test_sink,
+        Send(AllOf(
+            SourceFilename(Eq(__FILE__)),
+            SourceBasename(Eq("log_basic_test_impl.inc")),
+            SourceLine(Eq(log_line)), Prefix(IsTrue()),
+            LogSeverity(Eq(absl::LogSeverity::kError)),
+            Timestamp(InMatchWindow()),
+            ThreadID(Eq(absl::base_internal::GetTID())),
+            TextMessage(Eq("hello world")),
+            Verbosity(Eq(absl::LogEntry::kNoVerbosityLevel)),
+            ENCODED_MESSAGE(MatchesEvent(
+                Eq(__FILE__), Eq(log_line), InMatchWindow(),
+                Eq(logging::proto::ERROR), Eq(absl::base_internal::GetTID()),
+                ElementsAre(ValueWithLiteral(Eq("hello world"))))),
+            Stacktrace(IsEmpty()))));
+  }
+
+  test_sink.StartCapturingLogs();
+  do_log();
+}
+
 #if GTEST_HAS_DEATH_TEST
 using BasicLogDeathTest = BasicLogTest;
 
diff --git a/absl/numeric/BUILD.bazel b/absl/numeric/BUILD.bazel
index 4503a15..3c7a02f 100644
--- a/absl/numeric/BUILD.bazel
+++ b/absl/numeric/BUILD.bazel
@@ -56,7 +56,6 @@
         "//absl/base:core_headers",
         "//absl/random",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
@@ -115,8 +114,9 @@
     ],
 )
 
-cc_test(
+cc_binary(
     name = "int128_benchmark",
+    testonly = True,
     srcs = ["int128_benchmark.cc"],
     copts = ABSL_TEST_COPTS,
     linkopts = ABSL_DEFAULT_LINKOPTS,
@@ -125,7 +125,6 @@
         ":int128",
         "//absl/base:config",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
diff --git a/absl/numeric/bits_benchmark.cc b/absl/numeric/bits_benchmark.cc
index 2c89afd..429b4ca 100644
--- a/absl/numeric/bits_benchmark.cc
+++ b/absl/numeric/bits_benchmark.cc
@@ -15,10 +15,10 @@
 #include <cstdint>
 #include <vector>
 
-#include "benchmark/benchmark.h"
 #include "absl/base/optimization.h"
 #include "absl/numeric/bits.h"
 #include "absl/random/random.h"
+#include "benchmark/benchmark.h"
 
 namespace absl {
 namespace {
diff --git a/absl/numeric/int128_benchmark.cc b/absl/numeric/int128_benchmark.cc
index eab1515..e2e2de5 100644
--- a/absl/numeric/int128_benchmark.cc
+++ b/absl/numeric/int128_benchmark.cc
@@ -18,9 +18,9 @@
 #include <random>
 #include <vector>
 
-#include "benchmark/benchmark.h"
 #include "absl/base/config.h"
 #include "absl/numeric/int128.h"
+#include "benchmark/benchmark.h"
 
 namespace {
 
diff --git a/absl/status/BUILD.bazel b/absl/status/BUILD.bazel
index b0eb27a..b61abeb 100644
--- a/absl/status/BUILD.bazel
+++ b/absl/status/BUILD.bazel
@@ -86,6 +86,17 @@
     ],
 )
 
+cc_binary(
+    name = "status_benchmark",
+    testonly = True,
+    srcs = ["status_benchmark.cc"],
+    tags = ["benchmark"],
+    deps = [
+        ":status",
+        "@google_benchmark//:benchmark_main",
+    ],
+)
+
 cc_library(
     name = "statusor",
     srcs = [
@@ -132,6 +143,18 @@
     ],
 )
 
+cc_binary(
+    name = "statusor_benchmark",
+    testonly = True,
+    srcs = ["statusor_benchmark.cc"],
+    tags = ["benchmark"],
+    deps = [
+        ":status",
+        ":statusor",
+        "@google_benchmark//:benchmark_main",
+    ],
+)
+
 cc_library(
     name = "status_matchers",
     testonly = 1,
diff --git a/absl/status/status_benchmark.cc b/absl/status/status_benchmark.cc
new file mode 100644
index 0000000..a9146fb
--- /dev/null
+++ b/absl/status/status_benchmark.cc
@@ -0,0 +1,37 @@
+// Copyright 2025 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <utility>
+#include "absl/status/status.h"
+#include "benchmark/benchmark.h"
+
+namespace {
+
+void BM_CreateOk(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::Status s;  // ok.
+    benchmark::DoNotOptimize(s);
+  }
+}
+BENCHMARK(BM_CreateOk);
+
+void BM_CreateBad(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::Status s(absl::StatusCode::kInvalidArgument, "message");
+    benchmark::DoNotOptimize(s);
+  }
+}
+BENCHMARK(BM_CreateBad);
+
+}  // namespace
diff --git a/absl/status/statusor.h b/absl/status/statusor.h
index b1da45e..322d448 100644
--- a/absl/status/statusor.h
+++ b/absl/status/statusor.h
@@ -464,7 +464,7 @@
   // Returns a reference to the current `absl::Status` contained within the
   // `absl::StatusOr<T>`. If `absl::StatusOr<T>` contains a `T`, then this
   // function returns `absl::OkStatus()`.
-  const Status& status() const&;
+  ABSL_MUST_USE_RESULT const Status& status() const&;
   Status status() &&;
 
   // StatusOr<T>::value()
diff --git a/absl/status/statusor_benchmark.cc b/absl/status/statusor_benchmark.cc
new file mode 100644
index 0000000..bb99547
--- /dev/null
+++ b/absl/status/statusor_benchmark.cc
@@ -0,0 +1,480 @@
+// Copyright 2025 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <string>
+
+#include "absl/status/status.h"
+#include "absl/status/statusor.h"
+#include "benchmark/benchmark.h"
+
+namespace {
+
+void BM_StatusOrInt_CtorStatus(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<int> status(absl::CancelledError());
+    benchmark::DoNotOptimize(status);
+  }
+}
+BENCHMARK(BM_StatusOrInt_CtorStatus);
+
+void BM_StatusOrInt_CtorStatusWithMessage(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<int> status(
+        absl::UnknownError("This string is 28 characters"));
+    benchmark::DoNotOptimize(status);
+  }
+}
+BENCHMARK(BM_StatusOrInt_CtorStatusWithMessage);
+
+void BM_StatusOrInt_CopyCtor_Error(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<int> original(
+        absl::UnknownError("This string is 28 characters"));
+    benchmark::DoNotOptimize(original);
+    absl::StatusOr<int> status(original);
+    benchmark::DoNotOptimize(status);
+  }
+}
+BENCHMARK(BM_StatusOrInt_CopyCtor_Error);
+
+void BM_StatusOrInt_CopyCtor_Ok(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<int> original(42);
+    benchmark::DoNotOptimize(original);
+    absl::StatusOr<int> status(original);
+    benchmark::DoNotOptimize(status);
+  }
+}
+BENCHMARK(BM_StatusOrInt_CopyCtor_Ok);
+
+void BM_StatusOrInt_MoveCtor_Error(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<int> original(
+        absl::UnknownError("This string is 28 characters"));
+    benchmark::DoNotOptimize(original);
+    absl::StatusOr<int> status(std::move(original));
+    benchmark::DoNotOptimize(status);
+  }
+}
+BENCHMARK(BM_StatusOrInt_MoveCtor_Error);
+
+void BM_StatusOrInt_MoveCtor_Ok(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<int> original(42);
+    benchmark::DoNotOptimize(original);
+    absl::StatusOr<int> status(std::move(original));
+    benchmark::DoNotOptimize(status);
+  }
+}
+BENCHMARK(BM_StatusOrInt_MoveCtor_Ok);
+
+void BM_StatusOrInt_CopyAssign_Error(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<int> original(
+        absl::UnknownError("This string is 28 characters"));
+    benchmark::DoNotOptimize(original);
+    absl::StatusOr<int> status(42);
+    benchmark::DoNotOptimize(status);
+    benchmark::DoNotOptimize(status = original);
+    benchmark::DoNotOptimize(status);
+  }
+}
+BENCHMARK(BM_StatusOrInt_CopyAssign_Error);
+
+void BM_StatusOrInt_CopyAssign_Ok(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<int> original(42);
+    benchmark::DoNotOptimize(original);
+    absl::StatusOr<int> status(42);
+    benchmark::DoNotOptimize(status);
+    benchmark::DoNotOptimize(status = original);
+    benchmark::DoNotOptimize(status);
+  }
+}
+BENCHMARK(BM_StatusOrInt_CopyAssign_Ok);
+
+void BM_StatusOrInt_MoveAssign_Error(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<int> original(
+        absl::UnknownError("This string is 28 characters"));
+    benchmark::DoNotOptimize(original);
+    absl::StatusOr<int> status(42);
+    benchmark::DoNotOptimize(status);
+    benchmark::DoNotOptimize(status = std::move(original));
+    benchmark::DoNotOptimize(status);
+  }
+}
+BENCHMARK(BM_StatusOrInt_MoveAssign_Error);
+
+void BM_StatusOrInt_MoveAssign_Ok(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<int> original(42);
+    benchmark::DoNotOptimize(original);
+    absl::StatusOr<int> status(42);
+    benchmark::DoNotOptimize(status);
+    benchmark::DoNotOptimize(status = std::move(original));
+    benchmark::DoNotOptimize(status);
+  }
+}
+BENCHMARK(BM_StatusOrInt_MoveAssign_Ok);
+
+void BM_StatusOrInt_OkMethod_Error(benchmark::State& state) {
+  absl::StatusOr<int> status(
+      absl::UnknownError("This string is 28 characters"));
+  for (auto _ : state) {
+    benchmark::DoNotOptimize(status);
+    benchmark::DoNotOptimize(status.ok());
+  }
+}
+BENCHMARK(BM_StatusOrInt_OkMethod_Error);
+
+void BM_StatusOrInt_OkMethod_Ok(benchmark::State& state) {
+  absl::StatusOr<int> status(42);
+  for (auto _ : state) {
+    benchmark::DoNotOptimize(status);
+    benchmark::DoNotOptimize(status.ok());
+  }
+}
+BENCHMARK(BM_StatusOrInt_OkMethod_Ok);
+
+void BM_StatusOrInt_StatusMethod_Error(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<int> status(
+        absl::UnknownError("This string is 28 characters"));
+    benchmark::DoNotOptimize(status);
+    benchmark::DoNotOptimize(status.status().ok());
+  }
+}
+BENCHMARK(BM_StatusOrInt_StatusMethod_Error);
+
+void BM_StatusOrInt_StatusMethod_Ok(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<int> status(42);
+    benchmark::DoNotOptimize(status);
+    benchmark::DoNotOptimize(std::move(status).status().ok());
+  }
+}
+BENCHMARK(BM_StatusOrInt_StatusMethod_Ok);
+
+void BM_StatusOrInt_StatusMethodRvalue_Error(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<int> status(
+        absl::UnknownError("This string is 28 characters"));
+    benchmark::DoNotOptimize(status);
+    benchmark::DoNotOptimize(std::move(status).status().ok());
+  }
+}
+BENCHMARK(BM_StatusOrInt_StatusMethodRvalue_Error);
+
+void BM_StatusOrInt_StatusMethodRvalue_Ok(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<int> status(42);
+    benchmark::DoNotOptimize(status);
+    benchmark::DoNotOptimize(std::move(status).status());
+  }
+}
+BENCHMARK(BM_StatusOrInt_StatusMethodRvalue_Ok);
+
+void BM_StatusOrString_CtorStatus(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<std::string> status(absl::CancelledError());
+    benchmark::DoNotOptimize(status);
+  }
+}
+BENCHMARK(BM_StatusOrString_CtorStatus);
+
+void BM_StatusOrString_CtorStatusWithMessage(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<std::string> status(
+        absl::UnknownError("This string is 28 characters"));
+    benchmark::DoNotOptimize(status);
+  }
+}
+BENCHMARK(BM_StatusOrString_CtorStatusWithMessage);
+
+void BM_StatusOrString_CopyCtor_Error(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<std::string> original(
+        absl::UnknownError("This string is 28 characters"));
+    benchmark::DoNotOptimize(original);
+    absl::StatusOr<std::string> status(original);
+    benchmark::DoNotOptimize(status);
+  }
+}
+BENCHMARK(BM_StatusOrString_CopyCtor_Error);
+
+void BM_StatusOrString_CopyCtor_Ok(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<std::string> original("This string is 28 characters");
+    benchmark::DoNotOptimize(original);
+    absl::StatusOr<std::string> status(original);
+    benchmark::DoNotOptimize(status);
+  }
+}
+BENCHMARK(BM_StatusOrString_CopyCtor_Ok);
+
+void BM_StatusOrString_MoveCtor_Error(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<std::string> original(
+        absl::UnknownError("This string is 28 characters"));
+    benchmark::DoNotOptimize(original);
+    absl::StatusOr<std::string> status(std::move(original));
+    benchmark::DoNotOptimize(status);
+  }
+}
+BENCHMARK(BM_StatusOrString_MoveCtor_Error);
+
+void BM_StatusOrString_MoveCtor_Ok(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<std::string> original("This string is 28 characters");
+    benchmark::DoNotOptimize(original);
+    absl::StatusOr<std::string> status(std::move(original));
+    benchmark::DoNotOptimize(status);
+  }
+}
+BENCHMARK(BM_StatusOrString_MoveCtor_Ok);
+
+void BM_StatusOrString_CopyAssign_Error(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<std::string> original(
+        absl::UnknownError("This string is 28 characters"));
+    benchmark::DoNotOptimize(original);
+    absl::StatusOr<std::string> status("This string is 28 characters");
+    benchmark::DoNotOptimize(status);
+    benchmark::DoNotOptimize(status = original);
+    benchmark::DoNotOptimize(status);
+  }
+}
+BENCHMARK(BM_StatusOrString_CopyAssign_Error);
+
+void BM_StatusOrString_CopyAssign_Ok(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<std::string> original("This string is 28 characters");
+    benchmark::DoNotOptimize(original);
+    absl::StatusOr<std::string> status("This string is 28 characters");
+    benchmark::DoNotOptimize(status);
+    benchmark::DoNotOptimize(status = original);
+    benchmark::DoNotOptimize(status);
+  }
+}
+BENCHMARK(BM_StatusOrString_CopyAssign_Ok);
+
+void BM_StatusOrString_MoveAssign_Error(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<std::string> original(
+        absl::UnknownError("This string is 28 characters"));
+    benchmark::DoNotOptimize(original);
+    absl::StatusOr<std::string> status("This string is 28 characters");
+    benchmark::DoNotOptimize(status);
+    benchmark::DoNotOptimize(status = std::move(original));
+    benchmark::DoNotOptimize(status);
+  }
+}
+BENCHMARK(BM_StatusOrString_MoveAssign_Error);
+
+void BM_StatusOrString_MoveAssign_Ok(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<std::string> original("This string is 28 characters");
+    benchmark::DoNotOptimize(original);
+    absl::StatusOr<std::string> status("This string is 28 characters");
+    benchmark::DoNotOptimize(status);
+    benchmark::DoNotOptimize(status = std::move(original));
+    benchmark::DoNotOptimize(status);
+  }
+}
+BENCHMARK(BM_StatusOrString_MoveAssign_Ok);
+
+void BM_StatusOrString_OkMethod_Error(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<std::string> status(
+        absl::UnknownError("This string is 28 characters"));
+    benchmark::DoNotOptimize(status);
+    benchmark::DoNotOptimize(status.ok());
+  }
+}
+BENCHMARK(BM_StatusOrString_OkMethod_Error);
+
+void BM_StatusOrString_OkMethod_Ok(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<std::string> status("This string is 28 characters");
+    benchmark::DoNotOptimize(status);
+    benchmark::DoNotOptimize(status.ok());
+  }
+}
+BENCHMARK(BM_StatusOrString_OkMethod_Ok);
+
+void BM_StatusOrString_StatusMethod_Error(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<std::string> status(
+        absl::UnknownError("This string is 28 characters"));
+    benchmark::DoNotOptimize(status);
+    benchmark::DoNotOptimize(status.status().ok());
+  }
+}
+BENCHMARK(BM_StatusOrString_StatusMethod_Error);
+
+void BM_StatusOrString_StatusMethod_Ok(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<std::string> status("This string is 28 characters");
+    benchmark::DoNotOptimize(status);
+    benchmark::DoNotOptimize(status.status().ok());
+  }
+}
+BENCHMARK(BM_StatusOrString_StatusMethod_Ok);
+
+void BM_StatusOrString_StatusMethodRvalue_Error(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<std::string> status(
+        absl::UnknownError("This string is 28 characters"));
+    benchmark::DoNotOptimize(status);
+    benchmark::DoNotOptimize(std::move(status).status());
+  }
+}
+BENCHMARK(BM_StatusOrString_StatusMethodRvalue_Error);
+
+void BM_StatusOrString_StatusMethodRvalue_Ok(benchmark::State& state) {
+  for (auto _ : state) {
+    absl::StatusOr<std::string> status("This string is 28 characters");
+    benchmark::DoNotOptimize(status);
+    benchmark::DoNotOptimize(std::move(status).status());
+  }
+}
+BENCHMARK(BM_StatusOrString_StatusMethodRvalue_Ok);
+
+// Benchmarks comparing a few alternative ways of structuring an interface
+// for returning an int64 on success or an error.  See (a), (b), (c), (d)
+// below for the variants.
+bool bm_cond = true;
+
+bool SimpleIntInterface(int64_t* v) ABSL_ATTRIBUTE_NOINLINE;
+bool SimpleIntInterfaceWithErrorMessage(int64_t* v, std::string* msg)
+    ABSL_ATTRIBUTE_NOINLINE;
+absl::Status SimpleIntInterfaceWithErrorStatus(int64_t* v)
+    ABSL_ATTRIBUTE_NOINLINE;
+absl::StatusOr<int64_t> SimpleIntStatusOrInterface() ABSL_ATTRIBUTE_NOINLINE;
+
+// (a): Just a boolean return value with an out int64* parameter
+bool SimpleIntInterface(int64_t* v) {
+  benchmark::DoNotOptimize(bm_cond);
+  if (bm_cond) {
+    *v = 42;
+    return true;
+  } else {
+    return false;
+  }
+}
+
+// (b): A boolean return value and a string error message filled in on failure
+// and an out int64* parameter filled on success
+bool SimpleIntInterfaceWithErrorMessage(int64_t* v, std::string* msg) {
+  benchmark::DoNotOptimize(bm_cond);
+  if (bm_cond) {
+    *v = 42;
+    return true;
+  } else {
+    *msg = "This is an error message";
+    return false;
+  }
+}
+
+// (c): A Status return value with an out int64* parameter on success
+absl::Status SimpleIntInterfaceWithErrorStatus(int64_t* v) {
+  benchmark::DoNotOptimize(bm_cond);
+  if (bm_cond) {
+    *v = 42;
+    return absl::OkStatus();
+  } else {
+    return absl::UnknownError("This is an error message");
+  }
+}
+
+// (d): A StatusOr<int64> return value
+absl::StatusOr<int64_t> SimpleIntStatusOrInterface() {
+  benchmark::DoNotOptimize(bm_cond);
+  if (bm_cond) {
+    return 42;
+  } else {
+    return absl::StatusOr<int64_t>(
+        absl::UnknownError("This is an error message"));
+  }
+}
+
+void SetCondition(benchmark::State& state) {
+  bm_cond = (state.range(0) == 0);
+  state.SetLabel(bm_cond ? "Success" : "Failure");
+}
+
+void BM_SimpleIntInterface(benchmark::State& state) {
+  SetCondition(state);
+  int64_t sum = 0;
+  for (auto s : state) {
+    int64_t v;
+    if (SimpleIntInterface(&v)) {
+      sum += v;
+    }
+    benchmark::DoNotOptimize(sum);
+  }
+}
+
+void BM_SimpleIntInterfaceMsg(benchmark::State& state) {
+  SetCondition(state);
+  int64_t sum = 0;
+  std::string msg;
+  for (auto s : state) {
+    int64_t v;
+    if (SimpleIntInterfaceWithErrorMessage(&v, &msg)) {
+      sum += v;
+    }
+    benchmark::DoNotOptimize(sum);
+    benchmark::DoNotOptimize(msg);
+  }
+}
+
+void BM_SimpleIntInterfaceStatus(benchmark::State& state) {
+  SetCondition(state);
+  int64_t sum = 0;
+  for (auto s : state) {
+    int64_t v;
+    auto result = SimpleIntInterfaceWithErrorStatus(&v);
+    if (result.ok()) {
+      sum += v;
+    }
+    benchmark::DoNotOptimize(sum);
+  }
+}
+
+void BM_SimpleIntStatusOrInterface(benchmark::State& state) {
+  SetCondition(state);
+  int64_t sum = 0;
+  for (auto s : state) {
+    auto v_s = SimpleIntStatusOrInterface();
+    if (v_s.ok()) {
+      sum += *v_s;
+    }
+    benchmark::DoNotOptimize(sum);
+  }
+}
+
+// Ordered like this so all the success path benchmarks (Arg(0)) show up,
+// then all the failure benchmarks (Arg(1))
+BENCHMARK(BM_SimpleIntInterface)->Arg(0);
+BENCHMARK(BM_SimpleIntInterfaceMsg)->Arg(0);
+BENCHMARK(BM_SimpleIntInterfaceStatus)->Arg(0);
+BENCHMARK(BM_SimpleIntStatusOrInterface)->Arg(0);
+BENCHMARK(BM_SimpleIntInterface)->Arg(1);
+BENCHMARK(BM_SimpleIntInterfaceMsg)->Arg(1);
+BENCHMARK(BM_SimpleIntInterfaceStatus)->Arg(1);
+BENCHMARK(BM_SimpleIntStatusOrInterface)->Arg(1);
+
+}  // namespace
diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel
index cb8d900..ddc115d 100644
--- a/absl/strings/BUILD.bazel
+++ b/absl/strings/BUILD.bazel
@@ -172,8 +172,9 @@
     ],
 )
 
-cc_test(
+cc_binary(
     name = "escaping_benchmark",
+    testonly = True,
     srcs = [
         "escaping_benchmark.cc",
         "internal/escaping_test_common.h",
@@ -185,7 +186,6 @@
         ":strings",
         "//absl/base:raw_logging_internal",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
@@ -241,8 +241,9 @@
     ],
 )
 
-cc_test(
+cc_binary(
     name = "ascii_benchmark",
+    testonly = True,
     srcs = ["ascii_benchmark.cc"],
     copts = ABSL_TEST_COPTS,
     tags = ["benchmark"],
@@ -250,7 +251,6 @@
     deps = [
         ":strings",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
@@ -268,8 +268,25 @@
     ],
 )
 
-cc_test(
+cc_binary(
+    name = "damerau_levenshtein_distance_benchmark",
+    testonly = True,
+    srcs = [
+        "internal/damerau_levenshtein_distance_benchmark.cc",
+    ],
+    copts = ABSL_TEST_COPTS,
+    linkopts = ABSL_DEFAULT_LINKOPTS,
+    tags = ["benchmark"],
+    visibility = ["//visibility:private"],
+    deps = [
+        ":strings",
+        "@google_benchmark//:benchmark_main",
+    ],
+)
+
+cc_binary(
     name = "memutil_benchmark",
+    testonly = True,
     srcs = [
         "internal/memutil.h",
         "internal/memutil_benchmark.cc",
@@ -281,7 +298,6 @@
         ":strings",
         "//absl/base:core_headers",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
@@ -332,8 +348,9 @@
     ],
 )
 
-cc_test(
+cc_binary(
     name = "string_view_benchmark",
+    testonly = True,
     srcs = ["string_view_benchmark.cc"],
     copts = ABSL_TEST_COPTS,
     tags = ["benchmark"],
@@ -344,7 +361,6 @@
         "//absl/base:core_headers",
         "//absl/base:raw_logging_internal",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
@@ -365,9 +381,9 @@
     ],
 )
 
-cc_test(
+cc_binary(
     name = "charset_benchmark",
-    size = "small",
+    testonly = True,
     srcs = [
         "charset_benchmark.cc",
     ],
@@ -380,7 +396,6 @@
         ":charset",
         "//absl/log:check",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
@@ -928,7 +943,6 @@
     srcs = ["cordz_test.cc"],
     copts = ABSL_TEST_COPTS,
     tags = [
-        "benchmark",
         "no_test_android_arm",
         "no_test_android_arm64",
         "no_test_android_x86",
@@ -970,8 +984,25 @@
     ],
 )
 
-cc_test(
+cc_binary(
+    name = "substitute_benchmark",
+    testonly = True,
+    srcs = ["substitute_benchmark.cc"],
+    copts = ABSL_TEST_COPTS,
+    tags = [
+        "benchmark",
+    ],
+    visibility = ["//visibility:private"],
+    deps = [
+        ":strings",
+        "//absl/base:core_headers",
+        "@google_benchmark//:benchmark_main",
+    ],
+)
+
+cc_binary(
     name = "str_replace_benchmark",
+    testonly = True,
     srcs = ["str_replace_benchmark.cc"],
     copts = ABSL_TEST_COPTS,
     tags = ["benchmark"],
@@ -980,7 +1011,6 @@
         ":strings",
         "//absl/base:raw_logging_internal",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
@@ -1014,8 +1044,9 @@
     ],
 )
 
-cc_test(
+cc_binary(
     name = "str_split_benchmark",
+    testonly = True,
     srcs = ["str_split_benchmark.cc"],
     copts = ABSL_TEST_COPTS,
     tags = ["benchmark"],
@@ -1024,7 +1055,6 @@
         ":strings",
         "//absl/base:raw_logging_internal",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
@@ -1041,8 +1071,9 @@
     ],
 )
 
-cc_test(
+cc_binary(
     name = "ostringstream_benchmark",
+    testonly = True,
     srcs = ["internal/ostringstream_benchmark.cc"],
     copts = ABSL_TEST_COPTS,
     tags = ["benchmark"],
@@ -1050,7 +1081,6 @@
     deps = [
         ":internal",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
@@ -1086,8 +1116,9 @@
     ],
 )
 
-cc_test(
+cc_binary(
     name = "str_join_benchmark",
+    testonly = True,
     srcs = ["str_join_benchmark.cc"],
     copts = ABSL_TEST_COPTS,
     tags = ["benchmark"],
@@ -1095,7 +1126,6 @@
     deps = [
         ":strings",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
@@ -1114,18 +1144,19 @@
     ],
 )
 
-cc_test(
+cc_binary(
     name = "str_cat_benchmark",
+    testonly = True,
     srcs = ["str_cat_benchmark.cc"],
     copts = ABSL_TEST_COPTS,
     tags = ["benchmark"],
     visibility = ["//visibility:private"],
     deps = [
+        ":str_format",
         ":strings",
         "//absl/random",
         "//absl/random:distributions",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
@@ -1152,8 +1183,9 @@
     ],
 )
 
-cc_test(
+cc_binary(
     name = "numbers_benchmark",
+    testonly = True,
     srcs = ["numbers_benchmark.cc"],
     copts = ABSL_TEST_COPTS,
     tags = ["benchmark"],
@@ -1164,7 +1196,6 @@
         "//absl/random",
         "//absl/random:distributions",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
@@ -1226,8 +1257,9 @@
     ],
 )
 
-cc_test(
+cc_binary(
     name = "charconv_benchmark",
+    testonly = True,
     srcs = [
         "charconv_benchmark.cc",
     ],
@@ -1237,7 +1269,6 @@
     deps = [
         ":strings",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
diff --git a/absl/strings/ascii_benchmark.cc b/absl/strings/ascii_benchmark.cc
index e4d0196..a839019 100644
--- a/absl/strings/ascii_benchmark.cc
+++ b/absl/strings/ascii_benchmark.cc
@@ -12,15 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "absl/strings/ascii.h"
-
 #include <algorithm>
+#include <array>
 #include <cctype>
 #include <cstddef>
-#include <string>
-#include <array>
 #include <random>
+#include <string>
 
+#include "absl/strings/ascii.h"
 #include "benchmark/benchmark.h"
 
 namespace {
diff --git a/absl/strings/charconv_benchmark.cc b/absl/strings/charconv_benchmark.cc
index e8c7371..0ee9363 100644
--- a/absl/strings/charconv_benchmark.cc
+++ b/absl/strings/charconv_benchmark.cc
@@ -12,12 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "absl/strings/charconv.h"
-
 #include <cstdlib>
 #include <cstring>
 #include <string>
 
+#include "absl/strings/charconv.h"
 #include "benchmark/benchmark.h"
 
 namespace {
diff --git a/absl/strings/charset_benchmark.cc b/absl/strings/charset_benchmark.cc
index bf7ae56..7133985 100644
--- a/absl/strings/charset_benchmark.cc
+++ b/absl/strings/charset_benchmark.cc
@@ -14,9 +14,9 @@
 
 #include <cstdint>
 
-#include "benchmark/benchmark.h"
 #include "absl/log/check.h"
 #include "absl/strings/charset.h"
+#include "benchmark/benchmark.h"
 
 namespace {
 
diff --git a/absl/strings/escaping_benchmark.cc b/absl/strings/escaping_benchmark.cc
index 342fd14..32b8f6e 100644
--- a/absl/strings/escaping_benchmark.cc
+++ b/absl/strings/escaping_benchmark.cc
@@ -12,18 +12,17 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "absl/strings/escaping.h"
-
 #include <cstdint>
 #include <memory>
 #include <random>
 #include <string>
 
-#include "benchmark/benchmark.h"
 #include "absl/base/internal/raw_logging.h"
+#include "absl/strings/escaping.h"
 #include "absl/strings/internal/escaping_test_common.h"
 #include "absl/strings/str_cat.h"
 #include "absl/strings/string_view.h"
+#include "benchmark/benchmark.h"
 
 namespace {
 
diff --git a/absl/strings/internal/damerau_levenshtein_distance_benchmark.cc b/absl/strings/internal/damerau_levenshtein_distance_benchmark.cc
new file mode 100644
index 0000000..76d6db4
--- /dev/null
+++ b/absl/strings/internal/damerau_levenshtein_distance_benchmark.cc
@@ -0,0 +1,56 @@
+// Copyright 2022 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <string>
+
+#include "absl/strings/internal/damerau_levenshtein_distance.h"
+#include "benchmark/benchmark.h"
+
+namespace {
+
+std::string MakeTestString(int desired_length, int num_edits) {
+  std::string test(desired_length, 'x');
+  for (int i = 0; (i < num_edits) && (i * 8 < desired_length); ++i) {
+    test[i * 8] = 'y';
+  }
+  return test;
+}
+
+void BenchmarkArgs(benchmark::internal::Benchmark* benchmark) {
+  // Each column is 8 bytes.
+  const auto string_size = {1, 8, 64, 100};
+  const auto num_edits = {1, 2, 16, 16, 64, 80};
+  const auto distance_cap = {1, 2, 3, 16, 64, 80};
+  for (const int s : string_size) {
+    for (const int n : num_edits) {
+      for (const int d : distance_cap) {
+        if (n > s) continue;
+        benchmark->Args({s, n, d});
+      }
+    }
+  }
+}
+
+using absl::strings_internal::CappedDamerauLevenshteinDistance;
+void BM_Distance(benchmark::State& state) {
+  std::string s1 = MakeTestString(state.range(0), 0);
+  std::string s2 = MakeTestString(state.range(0), state.range(1));
+  const size_t cap = state.range(2);
+  for (auto _ : state) {
+    CappedDamerauLevenshteinDistance(s1, s2, cap);
+  }
+}
+BENCHMARK(BM_Distance)->Apply(BenchmarkArgs);
+
+}  // namespace
diff --git a/absl/strings/internal/memutil_benchmark.cc b/absl/strings/internal/memutil_benchmark.cc
index 61e323a..1186752 100644
--- a/absl/strings/internal/memutil_benchmark.cc
+++ b/absl/strings/internal/memutil_benchmark.cc
@@ -12,13 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "absl/strings/internal/memutil.h"
-
 #include <algorithm>
 #include <cstdlib>
 
-#include "benchmark/benchmark.h"
 #include "absl/strings/ascii.h"
+#include "absl/strings/internal/memutil.h"
+#include "benchmark/benchmark.h"
 
 // We fill the haystack with aaaaaaaaaaaaaaaaaa...aaaab.
 // That gives us:
diff --git a/absl/strings/internal/ostringstream_benchmark.cc b/absl/strings/internal/ostringstream_benchmark.cc
index 5979f18..a95cf4d 100644
--- a/absl/strings/internal/ostringstream_benchmark.cc
+++ b/absl/strings/internal/ostringstream_benchmark.cc
@@ -12,11 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "absl/strings/internal/ostringstream.h"
-
 #include <sstream>
 #include <string>
 
+#include "absl/strings/internal/ostringstream.h"
 #include "benchmark/benchmark.h"
 
 namespace {
diff --git a/absl/strings/numbers_benchmark.cc b/absl/strings/numbers_benchmark.cc
index e7cb60a..c58f861 100644
--- a/absl/strings/numbers_benchmark.cc
+++ b/absl/strings/numbers_benchmark.cc
@@ -19,12 +19,12 @@
 #include <type_traits>
 #include <vector>
 
-#include "benchmark/benchmark.h"
 #include "absl/base/internal/raw_logging.h"
 #include "absl/random/distributions.h"
 #include "absl/random/random.h"
 #include "absl/strings/numbers.h"
 #include "absl/strings/string_view.h"
+#include "benchmark/benchmark.h"
 
 namespace {
 
diff --git a/absl/strings/str_cat_benchmark.cc b/absl/strings/str_cat_benchmark.cc
index 0a851e7..7695e8f 100644
--- a/absl/strings/str_cat_benchmark.cc
+++ b/absl/strings/str_cat_benchmark.cc
@@ -21,12 +21,13 @@
 #include <tuple>
 #include <utility>
 
-#include "benchmark/benchmark.h"
 #include "absl/random/log_uniform_int_distribution.h"
 #include "absl/random/random.h"
 #include "absl/strings/str_cat.h"
+#include "absl/strings/str_format.h"
 #include "absl/strings/string_view.h"
 #include "absl/strings/substitute.h"
+#include "benchmark/benchmark.h"
 
 namespace {
 
@@ -111,6 +112,17 @@
 }
 BENCHMARK(BM_HexCat_By_StrCat);
 
+void BM_HexCat_By_StrFormat(benchmark::State& state) {
+  int i = 0;
+  for (auto _ : state) {
+    std::string result =
+        absl::StrFormat("%s %x", kStringOne, int64_t{i} + 0x10000000);
+    benchmark::DoNotOptimize(result);
+    i = IncrementAlternatingSign(i);
+  }
+}
+BENCHMARK(BM_HexCat_By_StrFormat);
+
 void BM_HexCat_By_Substitute(benchmark::State& state) {
   int i = 0;
   for (auto _ : state) {
@@ -145,6 +157,18 @@
 }
 BENCHMARK(BM_DoubleToString_By_SixDigits);
 
+void BM_FloatToString_By_StrFormat(benchmark::State& state) {
+  int i = 0;
+  float foo = 0.0f;
+  for (auto _ : state) {
+    std::string result =
+        absl::StrFormat("%f != %lld", foo += 1.001f, int64_t{i});
+    benchmark::DoNotOptimize(result);
+    i = IncrementAlternatingSign(i);
+  }
+}
+BENCHMARK(BM_FloatToString_By_StrFormat);
+
 template <typename Table, size_t... Index>
 void BM_StrAppendImpl(benchmark::State& state, Table table, size_t total_bytes,
                       std::index_sequence<Index...>) {
diff --git a/absl/strings/str_join_benchmark.cc b/absl/strings/str_join_benchmark.cc
index be7a725..ffe6696 100644
--- a/absl/strings/str_join_benchmark.cc
+++ b/absl/strings/str_join_benchmark.cc
@@ -13,13 +13,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "absl/strings/str_join.h"
-
 #include <string>
 #include <tuple>
-#include <vector>
 #include <utility>
+#include <vector>
 
+#include "absl/strings/str_join.h"
 #include "benchmark/benchmark.h"
 
 namespace {
diff --git a/absl/strings/str_replace_benchmark.cc b/absl/strings/str_replace_benchmark.cc
index 01331da..cbe7572 100644
--- a/absl/strings/str_replace_benchmark.cc
+++ b/absl/strings/str_replace_benchmark.cc
@@ -12,13 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "absl/strings/str_replace.h"
-
 #include <cstring>
 #include <string>
 
-#include "benchmark/benchmark.h"
 #include "absl/base/internal/raw_logging.h"
+#include "absl/strings/str_replace.h"
+#include "benchmark/benchmark.h"
 
 namespace {
 
diff --git a/absl/strings/str_split_benchmark.cc b/absl/strings/str_split_benchmark.cc
index 003a66b..5a2e953 100644
--- a/absl/strings/str_split_benchmark.cc
+++ b/absl/strings/str_split_benchmark.cc
@@ -12,8 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "absl/strings/str_split.h"
-
 #include <cstddef>
 #include <iterator>
 #include <string>
@@ -21,9 +19,10 @@
 #include <unordered_set>
 #include <vector>
 
-#include "benchmark/benchmark.h"
 #include "absl/base/internal/raw_logging.h"
+#include "absl/strings/str_split.h"
 #include "absl/strings/string_view.h"
+#include "benchmark/benchmark.h"
 
 namespace {
 
diff --git a/absl/strings/string_view_benchmark.cc b/absl/strings/string_view_benchmark.cc
index 98f747c..4e36687 100644
--- a/absl/strings/string_view_benchmark.cc
+++ b/absl/strings/string_view_benchmark.cc
@@ -12,8 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "absl/strings/string_view.h"
-
 #include <algorithm>
 #include <cstddef>
 #include <cstdint>
@@ -23,11 +21,12 @@
 #include <unordered_set>
 #include <vector>
 
-#include "benchmark/benchmark.h"
 #include "absl/base/attributes.h"
 #include "absl/base/internal/raw_logging.h"
 #include "absl/base/macros.h"
 #include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "benchmark/benchmark.h"
 
 namespace {
 
diff --git a/absl/strings/substitute_benchmark.cc b/absl/strings/substitute_benchmark.cc
new file mode 100644
index 0000000..e58ec86
--- /dev/null
+++ b/absl/strings/substitute_benchmark.cc
@@ -0,0 +1,158 @@
+// Copyright 2020 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <cstddef>
+#include <cstdint>
+#include <string>
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/substitute.h"
+#include "benchmark/benchmark.h"
+
+namespace {
+
+void BM_Substitute(benchmark::State& state) {
+  std::string s(state.range(0), 'x');
+  int64_t bytes = 0;
+  for (auto _ : state) {
+    std::string result = absl::Substitute("$0 $1 $2 $3 $4 $5 $6 $7 $8 $9 $$", s,
+                                          s, s, s, s, s, s, s, s, s);
+    bytes += result.size();
+  }
+  state.SetBytesProcessed(bytes);
+}
+BENCHMARK(BM_Substitute)->Range(0, 1024);
+
+// Like BM_Substitute, but use char* strings (which must then be copied
+// to STL strings) for all parameters.  This demonstrates that it is faster
+// to use absl::Substitute() even if your inputs are char* strings.
+void BM_SubstituteCstr(benchmark::State& state) {
+  std::string s(state.range(0), 'x');
+  int64_t bytes = 0;
+  for (auto _ : state) {
+    std::string result =
+        absl::Substitute("$0 $1 $2 $3 $4 $5 $6 $7 $8 $9 $$", s.c_str(),
+                         s.c_str(), s.c_str(), s.c_str(), s.c_str(), s.c_str(),
+                         s.c_str(), s.c_str(), s.c_str(), s.c_str());
+    bytes += result.size();
+  }
+  state.SetBytesProcessed(bytes);
+}
+BENCHMARK(BM_SubstituteCstr)->Range(0, 1024);
+
+// For comparison with BM_Substitute.
+void BM_StringPrintf(benchmark::State& state) {
+  std::string s(state.range(0), 'x');
+  int64_t bytes = 0;
+  for (auto _ : state) {
+    std::string result = absl::StrCat(s, " ", s, " ", s, " ", s, " ", s, " ", s,
+                                      " ", s, " ", s, " ", s, " ", s);
+    bytes += result.size();
+  }
+  state.SetBytesProcessed(bytes);
+}
+BENCHMARK(BM_StringPrintf)->Range(0, 1024);
+
+// Benchmark using absl::Substitute() together with SimpleItoa() to print
+// numbers.  This demonstrates that absl::Substitute() is faster than
+// StringPrintf() even when the inputs are numbers.
+void BM_SubstituteNumber(benchmark::State& state) {
+  const int n = state.range(0);
+  int64_t bytes = 0;
+  for (auto _ : state) {
+    std::string result =
+        absl::Substitute("$0 $1 $2 $3 $4 $5 $6 $7 $8 $9 $$", n, n + 1, n + 2,
+                         n + 3, n + 4, n + 5, n + 6, n + 7, n + 8, n + 9);
+    bytes += result.size();
+  }
+  state.SetBytesProcessed(bytes);
+}
+BENCHMARK(BM_SubstituteNumber)->Arg(0)->Arg(1 << 20);
+
+// For comparison with BM_SubstituteNumber.
+void BM_StrCatNumber(benchmark::State& state) {
+  const int n = state.range(0);
+  int64_t bytes = 0;
+  for (auto _ : state) {
+    std::string result =
+        absl::StrCat(n, " ", n + 1, " ", n + 2, " ", n + 3, " ", n + 4, " ",
+                     n + 5, " ", n + 6, " ", n + 7, " ", n + 8, " ", n + 9);
+    bytes += result.size();
+  }
+  state.SetBytesProcessed(bytes);
+}
+BENCHMARK(BM_StrCatNumber)->Arg(0)->Arg(1 << 20);
+
+// Benchmark using absl::Substitute() with a single substitution, to test the
+// speed at which it copies simple text.  Even in this case, it's faster
+// that StringPrintf().
+void BM_SubstituteSimpleText(benchmark::State& state) {
+  std::string s(state.range(0), 'x');
+  int64_t bytes = 0;
+  for (auto _ : state) {
+    std::string result = absl::Substitute("$0", s.c_str());
+    bytes += result.size();
+  }
+  state.SetBytesProcessed(bytes);
+}
+BENCHMARK(BM_SubstituteSimpleText)->Range(0, 1024);
+
+// For comparison with BM_SubstituteSimpleText.
+void BM_StrCatSimpleText(benchmark::State& state) {
+  std::string s(state.range(0), 'x');
+  int64_t bytes = 0;
+  for (auto _ : state) {
+    std::string result = absl::StrCat("", s);
+    bytes += result.size();
+  }
+  state.SetBytesProcessed(bytes);
+}
+BENCHMARK(BM_StrCatSimpleText)->Range(0, 1024);
+
+std::string MakeFormatByDensity(int density, bool subs_mode) {
+  std::string format((2 + density) * 10, 'x');
+  for (size_t i = 0; i < 10; ++i) {
+    format[density * i] = subs_mode ? '$' : '%';
+    format[density * i + 1] = subs_mode ? ('0' + i) : 's';
+  }
+  return format;
+}
+
+void BM_SubstituteDensity(benchmark::State& state) {
+  const std::string s(10, 'x');
+  const std::string format = MakeFormatByDensity(state.range(0), true);
+  int64_t bytes = 0;
+  for (auto _ : state) {
+    std::string result = absl::Substitute(format, s, s, s, s, s, s, s, s, s, s);
+    bytes += result.size();
+  }
+  state.SetBytesProcessed(bytes);
+}
+BENCHMARK(BM_SubstituteDensity)->Range(0, 256);
+
+void BM_StrCatDensity(benchmark::State& state) {
+  const std::string s(10, 'x');
+  const std::string format(state.range(0), 'x');
+  int64_t bytes = 0;
+  for (auto _ : state) {
+    std::string result =
+        absl::StrCat(s, format, s, format, s, format, s, format, s, format, s,
+                     format, s, format, s, format, s, format, s, format);
+    bytes += result.size();
+  }
+  state.SetBytesProcessed(bytes);
+}
+BENCHMARK(BM_StrCatDensity)->Range(0, 256);
+
+}  // namespace
diff --git a/absl/synchronization/BUILD.bazel b/absl/synchronization/BUILD.bazel
index 867e986..c3c271e 100644
--- a/absl/synchronization/BUILD.bazel
+++ b/absl/synchronization/BUILD.bazel
@@ -140,6 +140,7 @@
         "//absl/base:core_headers",
         "//absl/base:dynamic_annotations",
         "//absl/base:malloc_internal",
+        "//absl/base:nullability",
         "//absl/base:raw_logging_internal",
         "//absl/base:tracing_internal",
         "//absl/debugging:stacktrace",
@@ -230,7 +231,6 @@
         ":graphcycles_internal",
         "//absl/base:raw_logging_internal",
         "@google_benchmark//:benchmark_main",
-        "@googletest//:gtest",
     ],
 )
 
diff --git a/absl/synchronization/CMakeLists.txt b/absl/synchronization/CMakeLists.txt
index a745574..4d21067 100644
--- a/absl/synchronization/CMakeLists.txt
+++ b/absl/synchronization/CMakeLists.txt
@@ -109,6 +109,7 @@
     absl::core_headers
     absl::dynamic_annotations
     absl::malloc_internal
+    absl::nullability
     absl::raw_logging_internal
     absl::stacktrace
     absl::symbolize
diff --git a/absl/synchronization/internal/graphcycles_benchmark.cc b/absl/synchronization/internal/graphcycles_benchmark.cc
index 54823e0..9012801 100644
--- a/absl/synchronization/internal/graphcycles_benchmark.cc
+++ b/absl/synchronization/internal/graphcycles_benchmark.cc
@@ -12,14 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "absl/synchronization/internal/graphcycles.h"
-
 #include <algorithm>
 #include <cstdint>
 #include <vector>
 
-#include "benchmark/benchmark.h"
 #include "absl/base/internal/raw_logging.h"
+#include "absl/synchronization/internal/graphcycles.h"
+#include "benchmark/benchmark.h"
 
 namespace {
 
diff --git a/absl/synchronization/mutex.h b/absl/synchronization/mutex.h
index 9143688..77422a0 100644
--- a/absl/synchronization/mutex.h
+++ b/absl/synchronization/mutex.h
@@ -70,6 +70,7 @@
 #include "absl/base/internal/low_level_alloc.h"
 #include "absl/base/internal/thread_identity.h"
 #include "absl/base/internal/tsan_mutex_interface.h"
+#include "absl/base/nullability.h"
 #include "absl/base/port.h"
 #include "absl/base/thread_annotations.h"
 #include "absl/synchronization/internal/kernel_timeout.h"
@@ -580,14 +581,15 @@
   // Calls `mu->Lock()` and returns when that call returns. That is, `*mu` is
   // guaranteed to be locked when this object is constructed. Requires that
   // `mu` be dereferenceable.
-  explicit MutexLock(Mutex* mu) ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) : mu_(mu) {
+  explicit MutexLock(Mutex* absl_nonnull mu) ABSL_EXCLUSIVE_LOCK_FUNCTION(mu)
+      : mu_(mu) {
     this->mu_->Lock();
   }
 
   // Like above, but calls `mu->LockWhen(cond)` instead. That is, in addition to
   // the above, the condition given by `cond` is also guaranteed to hold when
   // this object is constructed.
-  explicit MutexLock(Mutex* mu, const Condition& cond)
+  explicit MutexLock(Mutex* absl_nonnull mu, const Condition& cond)
       ABSL_EXCLUSIVE_LOCK_FUNCTION(mu)
       : mu_(mu) {
     this->mu_->LockWhen(cond);
@@ -601,7 +603,7 @@
   ~MutexLock() ABSL_UNLOCK_FUNCTION() { this->mu_->Unlock(); }
 
  private:
-  Mutex* const mu_;
+  Mutex* absl_nonnull const mu_;
 };
 
 // ReaderMutexLock
@@ -610,11 +612,12 @@
 // releases a shared lock on a `Mutex` via RAII.
 class ABSL_SCOPED_LOCKABLE ReaderMutexLock {
  public:
-  explicit ReaderMutexLock(Mutex* mu) ABSL_SHARED_LOCK_FUNCTION(mu) : mu_(mu) {
+  explicit ReaderMutexLock(Mutex* absl_nonnull mu) ABSL_SHARED_LOCK_FUNCTION(mu)
+      : mu_(mu) {
     mu->ReaderLock();
   }
 
-  explicit ReaderMutexLock(Mutex* mu, const Condition& cond)
+  explicit ReaderMutexLock(Mutex* absl_nonnull mu, const Condition& cond)
       ABSL_SHARED_LOCK_FUNCTION(mu)
       : mu_(mu) {
     mu->ReaderLockWhen(cond);
@@ -628,7 +631,7 @@
   ~ReaderMutexLock() ABSL_UNLOCK_FUNCTION() { this->mu_->ReaderUnlock(); }
 
  private:
-  Mutex* const mu_;
+  Mutex* absl_nonnull const mu_;
 };
 
 // WriterMutexLock
diff --git a/absl/synchronization/mutex_test.cc b/absl/synchronization/mutex_test.cc
index 2dc4d73..d8c4fdf 100644
--- a/absl/synchronization/mutex_test.cc
+++ b/absl/synchronization/mutex_test.cc
@@ -1725,7 +1725,7 @@
 TEST(Mutex, LoggingAddressReuse) {
   // Repeatedly re-create a Mutex with debug logging at the same address.
   ScopedInvariantDebugging scoped_debugging;
-  alignas(absl::Mutex) char storage[sizeof(absl::Mutex)];
+  alignas(absl::Mutex) unsigned char storage[sizeof(absl::Mutex)];
   auto invariant =
       +[](void *alive) { EXPECT_TRUE(*static_cast<bool *>(alive)); };
   constexpr size_t kIters = 10;
diff --git a/absl/time/BUILD.bazel b/absl/time/BUILD.bazel
index b577d92..445bdcc 100644
--- a/absl/time/BUILD.bazel
+++ b/absl/time/BUILD.bazel
@@ -131,8 +131,9 @@
     ],
 )
 
-cc_test(
+cc_binary(
     name = "time_benchmark",
+    testonly = True,
     srcs = [
         "civil_time_benchmark.cc",
         "clock_benchmark.cc",