diff --git a/CMakeLists.txt b/CMakeLists.txt
index e09e335..d0c6e60 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -41,6 +41,11 @@
   cmake_policy(SET CMP0077 NEW)
 endif (POLICY CMP0077)
 
+# Allow the user to specify the MSVC runtime
+if (POLICY CMP0091)
+  cmake_policy(SET CMP0091 NEW)
+endif (POLICY CMP0091)
+
 # Set BUILD_TESTING to OFF by default.
 # This must come before the project() and include(CTest) lines.
 OPTION(BUILD_TESTING "Build tests" OFF)
diff --git a/absl/CMakeLists.txt b/absl/CMakeLists.txt
index fbfa782..a41e1ee 100644
--- a/absl/CMakeLists.txt
+++ b/absl/CMakeLists.txt
@@ -16,6 +16,7 @@
 
 add_subdirectory(base)
 add_subdirectory(algorithm)
+add_subdirectory(cleanup)
 add_subdirectory(container)
 add_subdirectory(debugging)
 add_subdirectory(flags)
diff --git a/absl/base/attributes.h b/absl/base/attributes.h
index cf2cb55..325e2f8 100644
--- a/absl/base/attributes.h
+++ b/absl/base/attributes.h
@@ -131,14 +131,14 @@
 // ABSL_ATTRIBUTE_WEAK
 //
 // Tags a function as weak for the purposes of compilation and linking.
-// Weak attributes currently do not work properly in LLVM's Windows backend,
-// so disable them there. See https://bugs.llvm.org/show_bug.cgi?id=37598
+// Weak attributes did not work properly in LLVM's Windows backend before
+// 9.0.0, so disable them there. See https://bugs.llvm.org/show_bug.cgi?id=37598
 // for further information.
 // The MinGW compiler doesn't complain about the weak attribute until the link
 // step, presumably because Windows doesn't use ELF binaries.
 #if (ABSL_HAVE_ATTRIBUTE(weak) ||                   \
      (defined(__GNUC__) && !defined(__clang__))) && \
-    !(defined(__llvm__) && defined(_WIN32)) && !defined(__MINGW32__)
+    (!defined(_WIN32) || __clang_major__ < 9) && !defined(__MINGW32__)
 #undef ABSL_ATTRIBUTE_WEAK
 #define ABSL_ATTRIBUTE_WEAK __attribute__((weak))
 #define ABSL_HAVE_ATTRIBUTE_WEAK 1
@@ -524,6 +524,13 @@
 // ABSL_ATTRIBUTE_UNUSED
 //
 // Prevents the compiler from complaining about variables that appear unused.
+//
+// For code or headers that are assured to only build with C++17 and up, prefer
+// just using the standard '[[maybe_unused]]' directly over this macro.
+//
+// Due to differences in positioning requirements between the old, compiler
+// specific __attribute__ syntax and the now standard [[maybe_unused]], this
+// macro does not attempt to take advantage of '[[maybe_unused]]'.
 #if ABSL_HAVE_ATTRIBUTE(unused) || (defined(__GNUC__) && !defined(__clang__))
 #undef ABSL_ATTRIBUTE_UNUSED
 #define ABSL_ATTRIBUTE_UNUSED __attribute__((__unused__))
diff --git a/absl/debugging/BUILD.bazel b/absl/debugging/BUILD.bazel
index e7fd115..5385bcb 100644
--- a/absl/debugging/BUILD.bazel
+++ b/absl/debugging/BUILD.bazel
@@ -260,6 +260,7 @@
     visibility = ["//visibility:private"],
     deps = [
         "//absl/base:config",
+        "//absl/base:core_headers",
     ],
 )
 
@@ -273,6 +274,7 @@
     visibility = ["//visibility:private"],
     deps = [
         "//absl/base:config",
+        "//absl/base:core_headers",
     ],
 )
 
diff --git a/absl/debugging/leak_check.cc b/absl/debugging/leak_check.cc
index db9d5d0..764ca0a 100644
--- a/absl/debugging/leak_check.cc
+++ b/absl/debugging/leak_check.cc
@@ -16,6 +16,7 @@
 // When lsan is not linked in, these functions are not available,
 // therefore Abseil code which depends on these functions is conditioned on the
 // definition of LEAK_SANITIZER.
+#include "absl/base/attributes.h"
 #include "absl/debugging/leak_check.h"
 
 #ifndef LEAK_SANITIZER
@@ -23,6 +24,7 @@
 namespace absl {
 ABSL_NAMESPACE_BEGIN
 bool HaveLeakSanitizer() { return false; }
+bool LeakCheckerIsActive() { return false; }
 void DoIgnoreLeak(const void*) { }
 void RegisterLivePointers(const void*, size_t) { }
 void UnRegisterLivePointers(const void*, size_t) { }
@@ -35,9 +37,22 @@
 
 #include <sanitizer/lsan_interface.h>
 
+#if ABSL_HAVE_ATTRIBUTE_WEAK
+extern "C" ABSL_ATTRIBUTE_WEAK int __lsan_is_turned_off();
+#endif
+
 namespace absl {
 ABSL_NAMESPACE_BEGIN
 bool HaveLeakSanitizer() { return true; }
+
+#if ABSL_HAVE_ATTRIBUTE_WEAK
+bool LeakCheckerIsActive() {
+  return !(&__lsan_is_turned_off && __lsan_is_turned_off());
+}
+#else
+bool LeakCheckerIsActive() { return true; }
+#endif
+
 bool FindAndReportLeaks() { return __lsan_do_recoverable_leak_check(); }
 void DoIgnoreLeak(const void* ptr) { __lsan_ignore_object(ptr); }
 void RegisterLivePointers(const void* ptr, size_t size) {
diff --git a/absl/debugging/leak_check.h b/absl/debugging/leak_check.h
index 61c3216..5fc2b05 100644
--- a/absl/debugging/leak_check.h
+++ b/absl/debugging/leak_check.h
@@ -43,6 +43,12 @@
 // currently built into this target.
 bool HaveLeakSanitizer();
 
+// LeakCheckerIsActive()
+//
+// Returns true if a leak-checking sanitizer (either ASan or standalone LSan) is
+// currently built into this target and is turned on.
+bool LeakCheckerIsActive();
+
 // DoIgnoreLeak()
 //
 // Implements `IgnoreLeak()` below. This function should usually
diff --git a/absl/debugging/leak_check_test.cc b/absl/debugging/leak_check_test.cc
index b5cc487..9fcfc8e 100644
--- a/absl/debugging/leak_check_test.cc
+++ b/absl/debugging/leak_check_test.cc
@@ -23,8 +23,10 @@
 TEST(LeakCheckTest, DetectLeakSanitizer) {
 #ifdef ABSL_EXPECT_LEAK_SANITIZER
   EXPECT_TRUE(absl::HaveLeakSanitizer());
+  EXPECT_TRUE(absl::LeakCheckerIsActive());
 #else
   EXPECT_FALSE(absl::HaveLeakSanitizer());
+  EXPECT_FALSE(absl::LeakCheckerIsActive());
 #endif
 }
 
diff --git a/absl/meta/type_traits.h b/absl/meta/type_traits.h
index d5cb5f3..b5427a4 100644
--- a/absl/meta/type_traits.h
+++ b/absl/meta/type_traits.h
@@ -499,6 +499,27 @@
 #endif  // ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
 };
 
+#if defined(__cpp_lib_remove_cvref) && __cpp_lib_remove_cvref >= 201711L
+template <typename T>
+using remove_cvref = std::remove_cvref<T>;
+
+template <typename T>
+using remove_cvref_t = typename std::remove_cvref<T>::type;
+#else
+// remove_cvref()
+//
+// C++11 compatible implementation of std::remove_cvref which was added in
+// C++20.
+template <typename T>
+struct remove_cvref {
+  using type =
+      typename std::remove_cv<typename std::remove_reference<T>::type>::type;
+};
+
+template <typename T>
+using remove_cvref_t = typename remove_cvref<T>::type;
+#endif
+
 namespace type_traits_internal {
 // is_trivially_copyable()
 //
diff --git a/absl/meta/type_traits_test.cc b/absl/meta/type_traits_test.cc
index 1aafd0d..0ef5b66 100644
--- a/absl/meta/type_traits_test.cc
+++ b/absl/meta/type_traits_test.cc
@@ -942,6 +942,34 @@
       absl::type_traits_internal::is_trivially_copyable<Trivial&>::value);
 }
 
+TEST(TypeTraitsTest, TestRemoveCVRef) {
+  EXPECT_TRUE(
+      (std::is_same<typename absl::remove_cvref<int>::type, int>::value));
+  EXPECT_TRUE(
+      (std::is_same<typename absl::remove_cvref<int&>::type, int>::value));
+  EXPECT_TRUE(
+      (std::is_same<typename absl::remove_cvref<int&&>::type, int>::value));
+  EXPECT_TRUE((
+      std::is_same<typename absl::remove_cvref<const int&>::type, int>::value));
+  EXPECT_TRUE(
+      (std::is_same<typename absl::remove_cvref<int*>::type, int*>::value));
+  // Does not remove const in this case.
+  EXPECT_TRUE((std::is_same<typename absl::remove_cvref<const int*>::type,
+                            const int*>::value));
+  EXPECT_TRUE((std::is_same<typename absl::remove_cvref<int[2]>::type,
+                            int[2]>::value));
+  EXPECT_TRUE((std::is_same<typename absl::remove_cvref<int(&)[2]>::type,
+                            int[2]>::value));
+  EXPECT_TRUE((std::is_same<typename absl::remove_cvref<int(&&)[2]>::type,
+                            int[2]>::value));
+  EXPECT_TRUE((std::is_same<typename absl::remove_cvref<const int[2]>::type,
+                            int[2]>::value));
+  EXPECT_TRUE((std::is_same<typename absl::remove_cvref<const int(&)[2]>::type,
+                            int[2]>::value));
+  EXPECT_TRUE((std::is_same<typename absl::remove_cvref<const int(&&)[2]>::type,
+                            int[2]>::value));
+}
+
 #define ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(trait_name, ...)          \
   EXPECT_TRUE((std::is_same<typename std::trait_name<__VA_ARGS__>::type, \
                             absl::trait_name##_t<__VA_ARGS__>>::value))
diff --git a/absl/status/status_test.cc b/absl/status/status_test.cc
index 0e1a43c..1b038f6 100644
--- a/absl/status/status_test.cc
+++ b/absl/status/status_test.cc
@@ -36,7 +36,9 @@
 // its creator, and its classifier.
 struct ErrorTest {
   absl::StatusCode code;
-  using Creator = absl::Status (*)(absl::string_view);
+  using Creator = absl::Status (*)(
+      absl::string_view
+  );
   using Classifier = bool (*)(const absl::Status&);
   Creator creator;
   Classifier classifier;
@@ -78,7 +80,9 @@
     // expected error code and message.
     std::string message =
         absl::StrCat("error code ", test.code, " test message");
-    absl::Status status = test.creator(message);
+    absl::Status status = test.creator(
+        message
+    );
     EXPECT_EQ(test.code, status.code());
     EXPECT_EQ(message, status.message());
 
diff --git a/absl/strings/cord.cc b/absl/strings/cord.cc
index 9353375..1c03a61 100644
--- a/absl/strings/cord.cc
+++ b/absl/strings/cord.cc
@@ -1688,6 +1688,8 @@
   } else if (rep->tag == EXTERNAL) {
     *fragment = absl::string_view(rep->external()->base, rep->length);
     return true;
+  } else if (rep->tag == RING) {
+    return rep->ring()->IsFlat(fragment);
   } else if (rep->tag == SUBSTRING) {
     CordRep* child = rep->substring()->child;
     if (child->tag >= FLAT) {
@@ -1698,6 +1700,9 @@
       *fragment = absl::string_view(
           child->external()->base + rep->substring()->start, rep->length);
       return true;
+    } else if (child->tag == RING) {
+      return child->ring()->IsFlat(rep->substring()->start, rep->length,
+                                   fragment);
     }
   }
   return false;
diff --git a/absl/strings/cord_ring_test.cc b/absl/strings/cord_ring_test.cc
index 7d75e10..2943cf3 100644
--- a/absl/strings/cord_ring_test.cc
+++ b/absl/strings/cord_ring_test.cc
@@ -31,9 +31,6 @@
 
 extern thread_local bool cord_ring;
 
-// TOOD(b/177688959): weird things happened with the original test
-#define ASAN_BUG_177688959_FIXED false
-
 namespace absl {
 ABSL_NAMESPACE_BEGIN
 namespace {
@@ -340,19 +337,15 @@
 class CordRingTest : public testing::Test {
  public:
   ~CordRingTest() override {
-#if ASAN_BUG_177688959_FIXED
     for (CordRep* rep : unrefs_) {
       CordRep::Unref(rep);
     }
-#endif
   }
 
   template <typename CordRepType>
   CordRepType* NeedsUnref(CordRepType* rep) {
     assert(rep);
-#if ASAN_BUG_177688959_FIXED
     unrefs_.push_back(rep);
-#endif
     return rep;
   }
 
@@ -362,26 +355,16 @@
     return NeedsUnref(rep);
   }
 
-  void Unref(CordRep* rep) {
-#if !ASAN_BUG_177688959_FIXED
-    CordRep::Unref(rep);
-#endif
-  }
-
  private:
-#if ASAN_BUG_177688959_FIXED
   std::vector<CordRep*> unrefs_;
-#endif
 };
 
 class CordRingTestWithParam : public testing::TestWithParam<TestParam> {
  public:
   ~CordRingTestWithParam() override {
-#if ASAN_BUG_177688959_FIXED
     for (CordRep* rep : unrefs_) {
       CordRep::Unref(rep);
     }
-#endif
   }
 
   CordRepRing* CreateWithCapacity(CordRep* child, size_t extra_capacity) {
@@ -400,9 +383,7 @@
   template <typename CordRepType>
   CordRepType* NeedsUnref(CordRepType* rep) {
     assert(rep);
-#if ASAN_BUG_177688959_FIXED
     unrefs_.push_back(rep);
-#endif
     return rep;
   }
 
@@ -412,43 +393,23 @@
     return NeedsUnref(rep);
   }
 
-  void Unref(CordRep* rep) {
-#if !ASAN_BUG_177688959_FIXED
-    CordRep::Unref(rep);
-#endif
-  }
-
   template <typename CordRepType>
   CordRepType* RefIfShared(CordRepType* rep) {
     return Shared() ? Ref(rep) : rep;
   }
 
-  void UnrefIfShared(CordRep* rep) {
-    if (Shared()) Unref(rep);
-  }
-
   template <typename CordRepType>
   CordRepType* RefIfInputShared(CordRepType* rep) {
     return InputShared() ? Ref(rep) : rep;
   }
 
-  void UnrefIfInputShared(CordRep* rep) {
-    if (InputShared()) Unref(rep);
-  }
-
   template <typename CordRepType>
   CordRepType* RefIfInputSharedIndirect(CordRepType* rep) {
     return InputSharedIndirect() ? Ref(rep) : rep;
   }
 
-  void UnrefIfInputSharedIndirect(CordRep* rep) {
-    if (InputSharedIndirect()) Unref(rep);
-  }
-
  private:
-#if ASAN_BUG_177688959_FIXED
   std::vector<CordRep*> unrefs_;
-#endif
 };
 
 class CordRingCreateTest : public CordRingTestWithParam {
@@ -520,26 +481,26 @@
   }
 };
 
-INSTANTIATE_TEST_CASE_P(WithParam, CordRingSubTest,
-                        testing::ValuesIn(CordRingSubTest::CreateTestParams()),
-                        TestParamToString);
+INSTANTIATE_TEST_SUITE_P(WithParam, CordRingSubTest,
+                         testing::ValuesIn(CordRingSubTest::CreateTestParams()),
+                         TestParamToString);
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     WithParam, CordRingCreateTest,
     testing::ValuesIn(CordRingCreateTest::CreateTestParams()),
     TestParamToString);
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     WithParam, CordRingCreateFromTreeTest,
     testing::ValuesIn(CordRingCreateFromTreeTest::CreateTestParams()),
     TestParamToString);
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     WithParam, CordRingBuildTest,
     testing::ValuesIn(CordRingBuildTest::CreateTestParams()),
     TestParamToString);
 
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
     WithParam, CordRingBuildInputTest,
     testing::ValuesIn(CordRingBuildInputTest::CreateTestParams()),
     TestParamToString);
@@ -550,7 +511,6 @@
   ASSERT_THAT(result, IsValidRingBuffer());
   EXPECT_THAT(result->length, Eq(str1.size()));
   EXPECT_THAT(ToFlats(result), ElementsAre(str1));
-  Unref(result);
 }
 
 TEST_P(CordRingCreateTest, CreateFromRing) {
@@ -559,8 +519,6 @@
   ASSERT_THAT(result, IsValidRingBuffer());
   EXPECT_THAT(result, EqIfPrivate(GetParam(), ring));
   EXPECT_THAT(ToFlats(result), ElementsAreArray(kFoxFlats));
-  UnrefIfShared(ring);
-  Unref(result);
 }
 
 TEST_P(CordRingCreateFromTreeTest, CreateFromSubstringRing) {
@@ -570,23 +528,20 @@
   ASSERT_THAT(result, IsValidRingBuffer());
   EXPECT_THAT(result, EqIfInputPrivate(GetParam(), ring));
   EXPECT_THAT(ToString(result), string_view(kFox).substr(2, 11));
-  UnrefIfInputSharedIndirect(ring);
-  UnrefIfInputShared(sub);
-  Unref(result);
 }
 
 TEST_F(CordRingTest, CreateWithIllegalExtraCapacity) {
-  CordRep* flat = NeedsUnref(MakeFlat("Hello world"));
 #if defined(ABSL_HAVE_EXCEPTIONS)
+  CordRep* flat = NeedsUnref(MakeFlat("Hello world"));
   try {
     CordRepRing::Create(flat, CordRepRing::kMaxCapacity);
     GTEST_FAIL() << "expected std::length_error exception";
   } catch (const std::length_error&) {
   }
 #elif defined(GTEST_HAS_DEATH_TEST)
+  CordRep* flat = NeedsUnref(MakeFlat("Hello world"));
   EXPECT_DEATH(CordRepRing::Create(flat, CordRepRing::kMaxCapacity), ".*");
 #endif
-  Unref(flat);
 }
 
 TEST_P(CordRingCreateFromTreeTest, CreateFromSubstringOfFlat) {
@@ -597,9 +552,6 @@
   ASSERT_THAT(result, IsValidRingBuffer());
   EXPECT_THAT(result->length, Eq(20));
   EXPECT_THAT(ToFlats(result), ElementsAre(str1.substr(4, 20)));
-  Unref(result);
-  UnrefIfInputShared(flat);
-  UnrefIfInputSharedIndirect(child);
 }
 
 TEST_P(CordRingCreateTest, CreateFromExternal) {
@@ -609,8 +561,6 @@
   ASSERT_THAT(result, IsValidRingBuffer());
   EXPECT_THAT(result->length, Eq(str1.size()));
   EXPECT_THAT(ToFlats(result), ElementsAre(str1));
-  Unref(result);
-  UnrefIfInputShared(child);
 }
 
 TEST_P(CordRingCreateFromTreeTest, CreateFromSubstringOfExternal) {
@@ -621,9 +571,6 @@
   ASSERT_THAT(result, IsValidRingBuffer());
   EXPECT_THAT(result->length, Eq(24));
   EXPECT_THAT(ToFlats(result), ElementsAre(str1.substr(1, 24)));
-  Unref(result);
-  UnrefIfInputShared(external);
-  UnrefIfInputSharedIndirect(child);
 }
 
 TEST_P(CordRingCreateFromTreeTest, CreateFromSubstringOfLargeExternal) {
@@ -637,9 +584,6 @@
   ASSERT_THAT(result, IsValidRingBuffer());
   EXPECT_THAT(result->length, Eq(str.size()));
   EXPECT_THAT(ToRawFlats(result), ElementsAre(str));
-  Unref(result);
-  UnrefIfInputShared(external);
-  UnrefIfInputSharedIndirect(child);
 }
 
 TEST_P(CordRingBuildInputTest, CreateFromConcat) {
@@ -652,10 +596,6 @@
   ASSERT_THAT(result, IsValidRingBuffer());
   EXPECT_THAT(result->length, Eq(26));
   EXPECT_THAT(ToString(result), Eq(kAlphabet));
-  UnrefIfInputSharedIndirect(flats[0]);
-  UnrefIfInputSharedIndirect(flats[3]);
-  UnrefIfInputShared(concat);
-  Unref(result);
 }
 
 TEST_P(CordRingBuildInputTest, CreateFromSubstringConcat) {
@@ -671,10 +611,6 @@
       ASSERT_THAT(result, IsValidRingBuffer());
       ASSERT_THAT(result->length, Eq(len));
       ASSERT_THAT(ToString(result), string_view(kAlphabet).substr(off, len));
-      UnrefIfInputSharedIndirect(flats[0]);
-      UnrefIfInputSharedIndirect(flats[3]);
-      UnrefIfInputShared(child);
-      Unref(result);
     }
   }
 }
@@ -689,7 +625,6 @@
   EXPECT_THAT(result->capacity(), Le(2 * 120 + 1));
   EXPECT_THAT(result->entries(), Eq(1));
   EXPECT_THAT(result->begin_pos(), Eq(0));
-  Unref(result);
 }
 
 TEST_P(CordRingCreateTest, EntryForNewFlat) {
@@ -700,7 +635,6 @@
   EXPECT_THAT(result->entry_child(0), Eq(child));
   EXPECT_THAT(result->entry_end_pos(0), Eq(str1.length()));
   EXPECT_THAT(result->entry_data_offset(0), Eq(0));
-  Unref(result);
 }
 
 TEST_P(CordRingCreateTest, EntryForNewFlatSubstring) {
@@ -712,7 +646,6 @@
   EXPECT_THAT(result->entry_child(0), Eq(child));
   EXPECT_THAT(result->entry_end_pos(0), Eq(26));
   EXPECT_THAT(result->entry_data_offset(0), Eq(10));
-  Unref(result);
 }
 
 TEST_P(CordRingBuildTest, AppendFlat) {
@@ -724,8 +657,6 @@
   EXPECT_THAT(result, EqIfPrivateAndCapacity(GetParam(), ring));
   EXPECT_THAT(result->length, Eq(str1.size() + str2.size()));
   EXPECT_THAT(ToFlats(result), ElementsAre(str1, str2));
-  UnrefIfShared(ring);
-  Unref(result);
 }
 
 TEST_P(CordRingBuildTest, PrependFlat) {
@@ -737,8 +668,6 @@
   EXPECT_THAT(result, EqIfPrivateAndCapacity(GetParam(), ring));
   EXPECT_THAT(result->length, Eq(str1.size() + str2.size()));
   EXPECT_THAT(ToFlats(result), ElementsAre(str2, str1));
-  UnrefIfShared(ring);
-  Unref(result);
 }
 
 TEST_P(CordRingBuildTest, AppendString) {
@@ -750,8 +679,6 @@
   EXPECT_THAT(result, EqIfPrivateAndCapacity(GetParam(), ring));
   EXPECT_THAT(result->length, Eq(str1.size() + str2.size()));
   EXPECT_THAT(ToFlats(result), ElementsAre(str1, str2));
-  UnrefIfShared(ring);
-  Unref(result);
 }
 
 TEST_P(CordRingBuildTest, AppendStringHavingExtra) {
@@ -762,8 +689,6 @@
   ASSERT_THAT(result, IsValidRingBuffer());
   EXPECT_THAT(result->length, Eq(str1.size() + str2.size()));
   EXPECT_THAT(result, EqIfPrivate(GetParam(), ring));
-  UnrefIfShared(ring);
-  Unref(result);
 }
 
 TEST_P(CordRingBuildTest, AppendStringHavingPartialExtra) {
@@ -790,8 +715,6 @@
   } else {
     EXPECT_THAT(ToFlats(result), ElementsAre(str1, str2));
   }
-  UnrefIfShared(ring);
-  Unref(result);
 }
 
 TEST_P(CordRingBuildTest, AppendStringHavingExtraInSubstring) {
@@ -808,8 +731,6 @@
   } else {
     EXPECT_THAT(ToFlats(result), ElementsAre("1234", str2));
   }
-  UnrefIfShared(ring);
-  Unref(result);
 }
 
 TEST_P(CordRingBuildTest, AppendStringHavingSharedExtra) {
@@ -839,8 +760,6 @@
     EXPECT_THAT(result, EqIfPrivateAndCapacity(GetParam(), ring));
     EXPECT_THAT(result->length, Eq(4 + str2.size()));
     EXPECT_THAT(ToFlats(result), ElementsAre("1234", str2));
-    UnrefIfShared(ring);
-    Unref(result);
 
     CordRep::Unref(shared_type == 1 ? flat1 : flat);
   }
@@ -857,8 +776,6 @@
   EXPECT_THAT(result->length, Eq(str1.size() + str2.size() + str3.size()));
   EXPECT_THAT(result, EqIfPrivateAndCapacity(GetParam(), ring));
   EXPECT_THAT(ToFlats(result), ElementsAre(str1, StrCat(str2, str3)));
-  UnrefIfShared(ring);
-  Unref(result);
 }
 
 TEST_P(CordRingBuildTest, PrependString) {
@@ -875,8 +792,6 @@
   }
   EXPECT_THAT(result->length, Eq(str1.size() + str2.size()));
   EXPECT_THAT(ToFlats(result), ElementsAre(str2, str1));
-  UnrefIfShared(ring);
-  Unref(result);
 }
 
 TEST_P(CordRingBuildTest, PrependStringHavingExtra) {
@@ -893,8 +808,6 @@
   } else {
     EXPECT_THAT(ToFlats(result), ElementsAre(str2, "1234"));
   }
-  UnrefIfShared(ring);
-  Unref(result);
 }
 
 TEST_P(CordRingBuildTest, PrependStringHavingSharedExtra) {
@@ -921,8 +834,6 @@
     EXPECT_THAT(result->length, Eq(str1a.size() + str2.size()));
     EXPECT_THAT(result, EqIfPrivateAndCapacity(GetParam(), ring));
     EXPECT_THAT(ToFlats(result), ElementsAre(str2, str1a));
-    UnrefIfShared(ring);
-    Unref(result);
     CordRep::Unref(shared_type == 1 ? flat1 : flat);
   }
 }
@@ -938,8 +849,6 @@
   EXPECT_THAT(result->length, Eq(str1.size() + str2.size() + str3.size()));
   EXPECT_THAT(result, EqIfPrivateAndCapacity(GetParam(), ring));
   EXPECT_THAT(ToFlats(result), ElementsAre(StrCat(str3, str2), str1));
-  UnrefIfShared(ring);
-  Unref(result);
 }
 
 TEST_P(CordRingBuildTest, AppendPrependStringMix) {
@@ -950,12 +859,10 @@
     result = CordRepRing::Prepend(result, flats[4 - i]);
     result = CordRepRing::Append(result, flats[4 + i]);
   }
-  UnrefIfShared(ring);
   NeedsUnref(result);
   ASSERT_THAT(result, IsValidRingBuffer());
   EXPECT_THAT(result, EqIfPrivateAndCapacity(GetParam(), ring));
   EXPECT_THAT(ToString(result), kFox);
-  Unref(result);
 }
 
 TEST_P(CordRingBuildTest, AppendPrependStringMixWithExtra) {
@@ -976,8 +883,6 @@
     EXPECT_THAT(ToFlats(result), ElementsAre("The quick brown fox ", "jumps ",
                                              "over the lazy dog"));
   }
-  UnrefIfShared(ring);
-  Unref(result);
 }
 
 TEST_P(CordRingBuildTest, AppendPrependStringMixWithPrependedExtra) {
@@ -998,8 +903,6 @@
     EXPECT_THAT(ToFlats(result), ElementsAre("The quick brown fox ", "jumps ",
                                              "over the lazy dog"));
   }
-  UnrefIfShared(ring);
-  Unref(result);
 }
 
 TEST_P(CordRingSubTest, SubRing) {
@@ -1011,7 +914,6 @@
     CordRepRing* ring = RefIfShared(FromFlats(flats, composition));
     CordRepRing* result = CordRepRing::SubRing(ring, offset, 0);
     EXPECT_THAT(result, nullptr);
-    UnrefIfShared(ring);
 
     for (size_t len = 1; len < all.size() - offset; ++len) {
       ring = RefIfShared(FromFlats(flats, composition));
@@ -1019,8 +921,6 @@
       ASSERT_THAT(result, IsValidRingBuffer());
       ASSERT_THAT(result, EqIfPrivate(GetParam(), ring));
       ASSERT_THAT(ToString(result), Eq(all.substr(offset, len)));
-      UnrefIfShared(ring);
-      Unref(result);
     }
   }
 }
@@ -1039,7 +939,6 @@
     CordRepRing* ring = RefIfShared(FromFlats(flats, composition));
     CordRepRing* result = CordRepRing::SubRing(ring, offset, 0);
     EXPECT_THAT(result, nullptr);
-    UnrefIfShared(ring);
 
     for (size_t len = all.size() - 30; len < all.size() - offset; ++len) {
       ring = RefIfShared(FromFlats(flats, composition));
@@ -1049,8 +948,6 @@
       auto str = ToString(result);
       ASSERT_THAT(str, SizeIs(len));
       ASSERT_THAT(str, Eq(all.substr(offset, len)));
-      UnrefIfShared(ring);
-      Unref(result);
     }
   }
 }
@@ -1063,7 +960,6 @@
   CordRepRing* ring = RefIfShared(FromFlats(flats, composition));
   CordRepRing* result = CordRepRing::RemovePrefix(ring, all.size());
   EXPECT_THAT(result, nullptr);
-  UnrefIfShared(ring);
 
   for (size_t len = 1; len < all.size(); ++len) {
     ring = RefIfShared(FromFlats(flats, composition));
@@ -1071,8 +967,6 @@
     ASSERT_THAT(result, IsValidRingBuffer());
     EXPECT_THAT(result, EqIfPrivate(GetParam(), ring));
     EXPECT_THAT(ToString(result), Eq(all.substr(len)));
-    UnrefIfShared(ring);
-    Unref(result);
   }
 }
 
@@ -1087,7 +981,6 @@
       ElementsAre(
           not_a_string_view(external1->base, 1 << 20).remove_prefix(1 << 16),
           not_a_string_view(external2->base, 1 << 20)));
-  Unref(result);
 }
 
 TEST_P(CordRingSubTest, RemoveSuffix) {
@@ -1098,7 +991,6 @@
   CordRepRing* ring = RefIfShared(FromFlats(flats, composition));
   CordRepRing* result = CordRepRing::RemoveSuffix(ring, all.size());
   EXPECT_THAT(result, nullptr);
-  UnrefIfShared(ring);
 
   for (size_t len = 1; len < all.size(); ++len) {
     ring = RefIfShared(FromFlats(flats, composition));
@@ -1106,8 +998,6 @@
     ASSERT_THAT(result, IsValidRingBuffer());
     EXPECT_THAT(result, EqIfPrivate(GetParam(), ring));
     EXPECT_THAT(ToString(result), Eq(all.substr(0, all.size() - len)));
-    UnrefIfShared(ring);
-    Unref(result);
   }
 }
 
@@ -1121,8 +1011,6 @@
   ASSERT_THAT(result, IsValidRingBuffer());
   EXPECT_THAT(result, EqIfPrivate(GetParam(), ring));
   EXPECT_THAT(ToFlats(result), ElementsAreArray(kFoxFlats));
-  UnrefIfShared(ring);
-  Unref(result);
 }
 
 TEST_P(CordRingBuildInputTest, AppendRingWithFlatOffset) {
@@ -1137,9 +1025,6 @@
   EXPECT_THAT(result, EqIfPrivateAndCapacity(GetParam(), ring));
   EXPECT_THAT(ToFlats(result), ElementsAre("Head", "brown ", "fox ", "jumps ",
                                            "over ", "the ", "lazy ", "dog"));
-  UnrefIfInputSharedIndirect(child);
-  UnrefIfShared(ring);
-  Unref(result);
 }
 
 TEST_P(CordRingBuildInputTest, AppendRingWithBrokenOffset) {
@@ -1154,9 +1039,6 @@
   EXPECT_THAT(result, EqIfPrivateAndCapacity(GetParam(), ring));
   EXPECT_THAT(ToFlats(result),
               ElementsAre("Head", "umps ", "over ", "the ", "lazy ", "dog"));
-  UnrefIfInputSharedIndirect(child);
-  UnrefIfShared(ring);
-  Unref(result);
 }
 
 TEST_P(CordRingBuildInputTest, AppendRingWithFlatLength) {
@@ -1171,9 +1053,6 @@
   EXPECT_THAT(result, EqIfPrivateAndCapacity(GetParam(), ring));
   EXPECT_THAT(ToFlats(result), ElementsAre("Head", "The ", "quick ", "brown ",
                                            "fox ", "jumps ", "over ", "the "));
-  UnrefIfInputSharedIndirect(child);
-  UnrefIfShared(ring);
-  Unref(result);
 }
 
 TEST_P(CordRingBuildTest, AppendRingWithBrokenFlatLength) {
@@ -1188,9 +1067,6 @@
   EXPECT_THAT(result, EqIfPrivateAndCapacity(GetParam(), ring));
   EXPECT_THAT(ToFlats(result), ElementsAre("Head", "The ", "quick ", "brown ",
                                            "fox ", "jumps ", "ov"));
-  UnrefIfInputSharedIndirect(child);
-  UnrefIfShared(ring);
-  Unref(result);
 }
 
 TEST_P(CordRingBuildTest, AppendRingMiddlePiece) {
@@ -1205,9 +1081,6 @@
   EXPECT_THAT(result, EqIfPrivateAndCapacity(GetParam(), ring));
   EXPECT_THAT(ToFlats(result),
               ElementsAre("Head", "ck ", "brown ", "fox ", "jum"));
-  UnrefIfInputSharedIndirect(child);
-  UnrefIfShared(ring);
-  Unref(result);
 }
 
 TEST_P(CordRingBuildTest, AppendRingSinglePiece) {
@@ -1221,10 +1094,6 @@
   ASSERT_THAT(result, IsValidRingBuffer());
   EXPECT_THAT(result, EqIfPrivateAndCapacity(GetParam(), ring));
   EXPECT_THAT(ToFlats(result), ElementsAre("Head", "row"));
-  UnrefIfInputSharedIndirect(child);
-  UnrefIfInputShared(stripped);
-  UnrefIfShared(ring);
-  Unref(result);
 }
 
 TEST_P(CordRingBuildInputTest, AppendRingSinglePieceWithPrefix) {
@@ -1242,10 +1111,6 @@
   ASSERT_THAT(result, IsValidRingBuffer());
   EXPECT_THAT(result, EqIfPrivateAndCapacity(GetParam(), ring));
   EXPECT_THAT(ToFlats(result), ElementsAre("Prepend", "Head", "row"));
-  UnrefIfInputSharedIndirect(child);
-  UnrefIfInputShared(stripped);
-  UnrefIfShared(ring);
-  Unref(result);
 }
 
 TEST_P(CordRingBuildInputTest, PrependRing) {
@@ -1259,9 +1124,6 @@
   ASSERT_THAT(result, IsValidRingBuffer());
   EXPECT_THAT(result, EqIfPrivateAndCapacity(GetParam(), ring));
   EXPECT_THAT(ToFlats(result), ElementsAreArray(kFoxFlats));
-  UnrefIfInputShared(child);
-  UnrefIfShared(ring);
-  Unref(result);
 }
 
 TEST_P(CordRingBuildInputTest, PrependRingWithFlatOffset) {
@@ -1276,10 +1138,6 @@
   EXPECT_THAT(result, EqIfPrivateAndCapacity(GetParam(), ring));
   EXPECT_THAT(ToFlats(result), ElementsAre("brown ", "fox ", "jumps ", "over ",
                                            "the ", "lazy ", "dog", "Tail"));
-  UnrefIfInputShared(child);
-  UnrefIfInputSharedIndirect(stripped);
-  UnrefIfShared(ring);
-  Unref(result);
 }
 
 TEST_P(CordRingBuildInputTest, PrependRingWithBrokenOffset) {
@@ -1293,10 +1151,6 @@
   EXPECT_THAT(result, EqIfPrivateAndCapacity(GetParam(), ring));
   EXPECT_THAT(ToFlats(result),
               ElementsAre("umps ", "over ", "the ", "lazy ", "dog", "Tail"));
-  UnrefIfInputShared(child);
-  UnrefIfInputSharedIndirect(stripped);
-  UnrefIfShared(ring);
-  Unref(result);
 }
 
 TEST_P(CordRingBuildInputTest, PrependRingWithFlatLength) {
@@ -1311,10 +1165,6 @@
   EXPECT_THAT(result, EqIfPrivateAndCapacity(GetParam(), ring));
   EXPECT_THAT(ToFlats(result), ElementsAre("The ", "quick ", "brown ", "fox ",
                                            "jumps ", "over ", "the ", "Tail"));
-  UnrefIfShared(ring);
-  UnrefIfInputShared(child);
-  UnrefIfInputSharedIndirect(stripped);
-  Unref(result);
 }
 
 TEST_P(CordRingBuildInputTest, PrependRingWithBrokenFlatLength) {
@@ -1329,10 +1179,6 @@
   EXPECT_THAT(result, EqIfPrivateAndCapacity(GetParam(), ring));
   EXPECT_THAT(ToFlats(result), ElementsAre("The ", "quick ", "brown ", "fox ",
                                            "jumps ", "ov", "Tail"));
-  UnrefIfInputShared(child);
-  UnrefIfInputSharedIndirect(stripped);
-  UnrefIfShared(ring);
-  Unref(result);
 }
 
 TEST_P(CordRingBuildInputTest, PrependRingMiddlePiece) {
@@ -1348,10 +1194,6 @@
   EXPECT_THAT(result, EqIfPrivateAndCapacity(GetParam(), ring));
   EXPECT_THAT(ToFlats(result),
               ElementsAre("ck ", "brown ", "fox ", "jum", "Tail"));
-  UnrefIfInputShared(child);
-  UnrefIfInputSharedIndirect(stripped);
-  UnrefIfShared(ring);
-  Unref(result);
 }
 
 TEST_P(CordRingBuildInputTest, PrependRingSinglePiece) {
@@ -1365,10 +1207,6 @@
   ASSERT_THAT(result, IsValidRingBuffer());
   EXPECT_THAT(result, EqIfPrivateAndCapacity(GetParam(), ring));
   EXPECT_THAT(ToFlats(result), ElementsAre("row", "Tail"));
-  UnrefIfInputShared(child);
-  UnrefIfInputSharedIndirect(stripped);
-  UnrefIfShared(ring);
-  Unref(result);
 }
 
 TEST_P(CordRingBuildInputTest, PrependRingSinglePieceWithPrefix) {
@@ -1385,10 +1223,6 @@
   ASSERT_THAT(result, IsValidRingBuffer());
   EXPECT_THAT(result, EqIfPrivateAndCapacity(GetParam(), ring));
   EXPECT_THAT(ToFlats(result), ElementsAre("row", "Prepend", "Tail"));
-  UnrefIfInputShared(child);
-  UnrefIfInputSharedIndirect(stripped);
-  UnrefIfShared(ring);
-  Unref(result);
 }
 
 TEST_F(CordRingTest, Find) {
@@ -1406,7 +1240,6 @@
     ASSERT_THAT(found.offset, Lt(data.length()));
     ASSERT_THAT(data[found.offset], Eq(value[i]));
   }
-  Unref(ring);
 }
 
 TEST_F(CordRingTest, FindWithHint) {
@@ -1442,7 +1275,6 @@
     ++flat_pos;
     flat_offset += flat.length();
   }
-  Unref(ring);
 }
 
 TEST_F(CordRingTest, FindInLargeRing) {
@@ -1464,7 +1296,6 @@
     ASSERT_THAT(pos.offset, Lt(data.length()));
     ASSERT_THAT(data[pos.offset], Eq(value[i]));
   }
-  Unref(ring);
 }
 
 TEST_F(CordRingTest, FindTail) {
@@ -1483,7 +1314,6 @@
     ASSERT_THAT(pos.offset, Lt(data.length()));
     ASSERT_THAT(data[data.length() - pos.offset - 1], Eq(value[i]));
   }
-  Unref(ring);
 }
 
 TEST_F(CordRingTest, FindTailWithHint) {
@@ -1510,7 +1340,6 @@
     ASSERT_THAT(pos.offset, Lt(data.length()));
     ASSERT_THAT(data[data.length() - pos.offset - 1], Eq(value[i]));
   }
-  Unref(ring);
 }
 
 TEST_F(CordRingTest, FindTailInLargeRing) {
@@ -1532,7 +1361,6 @@
     ASSERT_THAT(pos.offset, Lt(data.length()));
     ASSERT_THAT(data[data.length() - pos.offset - 1], Eq(value[i]));
   }
-  Unref(ring);
 }
 
 TEST_F(CordRingTest, GetCharacter) {
@@ -1544,7 +1372,6 @@
   for (int i = 0; i < value.length(); ++i) {
     ASSERT_THAT(result->GetCharacter(i), Eq(value[i]));
   }
-  Unref(result);
 }
 
 TEST_F(CordRingTest, GetCharacterWithSubstring) {
@@ -1556,7 +1383,67 @@
   for (int i = 0; i < value.length(); ++i) {
     ASSERT_THAT(result->GetCharacter(i), Eq(value[i]));
   }
-  Unref(result);
+}
+
+TEST_F(CordRingTest, IsFlatSingleFlat) {
+  for (bool external : {false, true}) {
+    SCOPED_TRACE(external ? "With External" : "With Flat");
+    absl::string_view str = "Hello world";
+    CordRep* rep = external ? MakeExternal(str) : MakeFlat(str);
+    CordRepRing* ring = NeedsUnref(CordRepRing::Create(rep));
+
+    // The ring is a single non-fragmented flat:
+    absl::string_view fragment;
+    EXPECT_TRUE(ring->IsFlat(nullptr));
+    EXPECT_TRUE(ring->IsFlat(&fragment));
+    EXPECT_THAT(fragment, Eq("Hello world"));
+    fragment = "";
+    EXPECT_TRUE(ring->IsFlat(0, 11, nullptr));
+    EXPECT_TRUE(ring->IsFlat(0, 11, &fragment));
+    EXPECT_THAT(fragment, Eq("Hello world"));
+
+    // Arbitrary ranges must check true as well.
+    EXPECT_TRUE(ring->IsFlat(1, 4, &fragment));
+    EXPECT_THAT(fragment, Eq("ello"));
+    EXPECT_TRUE(ring->IsFlat(6, 5, &fragment));
+    EXPECT_THAT(fragment, Eq("world"));
+  }
+}
+
+TEST_F(CordRingTest, IsFlatMultiFlat) {
+  for (bool external : {false, true}) {
+    SCOPED_TRACE(external ? "With External" : "With Flat");
+    absl::string_view str1 = "Hello world";
+    absl::string_view str2 = "Halt and catch fire";
+    CordRep* rep1 = external ? MakeExternal(str1) : MakeFlat(str1);
+    CordRep* rep2 = external ? MakeExternal(str2) : MakeFlat(str2);
+    CordRepRing* ring = CordRepRing::Append(CordRepRing::Create(rep1), rep2);
+    NeedsUnref(ring);
+
+    // The ring is fragmented, IsFlat() on the entire cord must be false.
+    EXPECT_FALSE(ring->IsFlat(nullptr));
+    absl::string_view fragment = "Don't touch this";
+    EXPECT_FALSE(ring->IsFlat(&fragment));
+    EXPECT_THAT(fragment, Eq("Don't touch this"));
+
+    // Check for ranges exactly within both flats.
+    EXPECT_TRUE(ring->IsFlat(0, 11, &fragment));
+    EXPECT_THAT(fragment, Eq("Hello world"));
+    EXPECT_TRUE(ring->IsFlat(11, 19, &fragment));
+    EXPECT_THAT(fragment, Eq("Halt and catch fire"));
+
+    // Check for arbitrary partial range inside each flat.
+    EXPECT_TRUE(ring->IsFlat(1, 4, &fragment));
+    EXPECT_THAT(fragment, "ello");
+    EXPECT_TRUE(ring->IsFlat(26, 4, &fragment));
+    EXPECT_THAT(fragment, "fire");
+
+    // Check ranges spanning across both flats
+    fragment = "Don't touch this";
+    EXPECT_FALSE(ring->IsFlat(1, 18, &fragment));
+    EXPECT_FALSE(ring->IsFlat(10, 2, &fragment));
+    EXPECT_THAT(fragment, Eq("Don't touch this"));
+  }
 }
 
 TEST_F(CordRingTest, Dump) {
@@ -1564,7 +1451,6 @@
   auto flats = MakeSpan(kFoxFlats);
   CordRepRing* ring = NeedsUnref(FromFlats(flats, kPrepend));
   ss << *ring;
-  Unref(ring);
 }
 
 }  // namespace
diff --git a/absl/strings/cord_test.cc b/absl/strings/cord_test.cc
index f998242..fb67341 100644
--- a/absl/strings/cord_test.cc
+++ b/absl/strings/cord_test.cc
@@ -187,6 +187,18 @@
   static cord_internal::CordzInfo* GetCordzInfo(const Cord& c) {
     return c.contents_.cordz_info();
   }
+
+  static Cord MakeSubstring(Cord src, size_t offset, size_t length) {
+    Cord cord = src;
+    ABSL_RAW_CHECK(cord.contents_.is_tree(), "Can not be inlined");
+    auto* rep = new cord_internal::CordRepSubstring;
+    rep->tag = cord_internal::SUBSTRING;
+    rep->child = cord.contents_.tree();
+    rep->start = offset;
+    rep->length = length;
+    cord.contents_.replace_tree(rep);
+    return cord;
+  }
 };
 
 ABSL_NAMESPACE_END
@@ -466,8 +478,8 @@
 
 TEST(TryFlat, SubstrFlat) {
   absl::Cord c("longer than 15 bytes");
-  c.RemovePrefix(1);
-  EXPECT_EQ(c.TryFlat(), "onger than 15 bytes");
+  absl::Cord sub = absl::CordTestPeer::MakeSubstring(c, 1, c.size() - 1);
+  EXPECT_EQ(sub.TryFlat(), "onger than 15 bytes");
 }
 
 TEST(TryFlat, Concat) {
@@ -482,16 +494,46 @@
 
 TEST(TryFlat, SubstrExternal) {
   absl::Cord c = absl::MakeCordFromExternal("hell", [](absl::string_view) {});
-  c.RemovePrefix(1);
-  EXPECT_EQ(c.TryFlat(), "ell");
+  absl::Cord sub = absl::CordTestPeer::MakeSubstring(c, 1, c.size() - 1);
+  EXPECT_EQ(sub.TryFlat(), "ell");
 }
 
 TEST(TryFlat, SubstrConcat) {
   absl::Cord c = absl::MakeFragmentedCord({"hello", " world"});
+  absl::Cord sub = absl::CordTestPeer::MakeSubstring(c, 1, c.size() - 1);
+  EXPECT_EQ(sub.TryFlat(), absl::nullopt);
   c.RemovePrefix(1);
   EXPECT_EQ(c.TryFlat(), absl::nullopt);
 }
 
+TEST(TryFlat, CommonlyAssumedInvariants) {
+  // The behavior tested below is not part of the API contract of Cord, but it's
+  // something we intend to be true in our current implementation.  This test
+  // exists to detect and prevent accidental breakage of the implementation.
+  absl::string_view fragments[] = {"A fragmented test",
+                                   " cord",
+                                   " to test subcords",
+                                   " of ",
+                                   "a",
+                                   " cord for",
+                                   " each chunk "
+                                   "returned by the ",
+                                   "iterator"};
+  absl::Cord c = absl::MakeFragmentedCord(fragments);
+  int fragment = 0;
+  int offset = 0;
+  absl::Cord::CharIterator itc = c.char_begin();
+  for (absl::string_view sv : c.Chunks()) {
+    absl::string_view expected = fragments[fragment];
+    absl::Cord subcord1 = c.Subcord(offset, sv.length());
+    absl::Cord subcord2 = absl::Cord::AdvanceAndRead(&itc, sv.size());
+    EXPECT_EQ(subcord1.TryFlat(), expected);
+    EXPECT_EQ(subcord2.TryFlat(), expected);
+    ++fragment;
+    offset += sv.length();
+  }
+}
+
 static bool IsFlat(const absl::Cord& c) {
   return c.chunk_begin() == c.chunk_end() || ++c.chunk_begin() == c.chunk_end();
 }
diff --git a/absl/strings/internal/cord_rep_ring.h b/absl/strings/internal/cord_rep_ring.h
index c74d335..830f2b2 100644
--- a/absl/strings/internal/cord_rep_ring.h
+++ b/absl/strings/internal/cord_rep_ring.h
@@ -237,6 +237,18 @@
   // Returns the character at `offset`. Requires that `offset < length`.
   char GetCharacter(size_t offset) const;
 
+  // Returns true if this instance manages a single contiguous buffer, in which
+  // case the (optional) output parameter `fragment` is set. Otherwise, the
+  // function returns false, and `fragment` is left unchanged.
+  bool IsFlat(absl::string_view* fragment) const;
+
+  // Returns true if the data starting at `offset` with length `length` is
+  // managed by this instance inside a single contiguous buffer, in which case
+  // the (optional) output parameter `fragment` is set to the contiguous memory
+  // starting at offset `offset` with length `length`. Otherwise, the function
+  // returns false, and `fragment` is left unchanged.
+  bool IsFlat(size_t offset, size_t length, absl::string_view* fragment) const;
+
   // Testing only: set capacity to requested capacity.
   void SetCapacityForTesting(size_t capacity);
 
@@ -576,6 +588,25 @@
   return static_cast<const CordRepRing*>(this);
 }
 
+inline bool CordRepRing::IsFlat(absl::string_view* fragment) const {
+  if (entries() == 1) {
+    if (fragment) *fragment = entry_data(head());
+    return true;
+  }
+  return false;
+}
+
+inline bool CordRepRing::IsFlat(size_t offset, size_t length,
+                                absl::string_view* fragment) const {
+  const Position pos = Find(offset);
+  const absl::string_view data = entry_data(pos.index);
+  if (data.length() >= length && data.length() - length >= pos.offset) {
+    if (fragment) *fragment = data.substr(pos.offset, length);
+    return true;
+  }
+  return false;
+}
+
 std::ostream& operator<<(std::ostream& s, const CordRepRing& rep);
 
 #ifdef __clang__
diff --git a/absl/strings/string_view.h b/absl/strings/string_view.h
index 5260b5b..b276bdb 100644
--- a/absl/strings/string_view.h
+++ b/absl/strings/string_view.h
@@ -398,12 +398,10 @@
 
   // string_view::compare()
   //
-  // Performs a lexicographical comparison between the `string_view` and
-  // another `absl::string_view`, returning -1 if `this` is less than, 0 if
-  // `this` is equal to, and 1 if `this` is greater than the passed string
-  // view. Note that in the case of data equality, a further comparison is made
-  // on the respective sizes of the two `string_view`s to determine which is
-  // smaller, equal, or greater.
+  // Performs a lexicographical comparison between this `string_view` and
+  // another `string_view` `x`, returning a negative value if `*this` is less
+  // than `x`, 0 if `*this` is equal to `x`, and a positive value if `*this`
+  // is greater than `x`.
   constexpr int compare(string_view x) const noexcept {
     return CompareImpl(length_, x.length_,
                        Min(length_, x.length_) == 0
diff --git a/absl/time/time.h b/absl/time/time.h
index d9ad1ae..2df6858 100644
--- a/absl/time/time.h
+++ b/absl/time/time.h
@@ -1180,11 +1180,15 @@
 //
 // Converts the `tm_year`, `tm_mon`, `tm_mday`, `tm_hour`, `tm_min`, and
 // `tm_sec` fields to an `absl::Time` using the given time zone. See ctime(3)
-// for a description of the expected values of the tm fields. If the indicated
-// time instant is not unique (see `absl::TimeZone::At(absl::CivilSecond)`
-// above), the `tm_isdst` field is consulted to select the desired instant
-// (`tm_isdst` > 0 means DST, `tm_isdst` == 0 means no DST, `tm_isdst` < 0
-// means use the post-transition offset).
+// for a description of the expected values of the tm fields. If the civil time
+// is unique (see `absl::TimeZone::At(absl::CivilSecond)` above), the matching
+// time instant is returned.  Otherwise, the `tm_isdst` field is consulted to
+// choose between the possible results.  For a repeated civil time, `tm_isdst !=
+// 0` returns the matching DST instant, while `tm_isdst == 0` returns the
+// matching non-DST instant.  For a skipped civil time there is no matching
+// instant, so `tm_isdst != 0` returns the DST instant, and `tm_isdst == 0`
+// returns the non-DST instant, that would have matched if the transition never
+// happened.
 Time FromTM(const struct tm& tm, TimeZone tz);
 
 // ToTM()
diff --git a/ci/macos_xcode_bazel.sh b/ci/macos_xcode_bazel.sh
index 738adf9..9e14e66 100755
--- a/ci/macos_xcode_bazel.sh
+++ b/ci/macos_xcode_bazel.sh
@@ -24,7 +24,7 @@
 fi
 
 # If we are running on Kokoro, check for a versioned Bazel binary.
-KOKORO_GFILE_BAZEL_BIN="bazel-2.0.0-darwin-x86_64"
+KOKORO_GFILE_BAZEL_BIN="bazel-3.7.0-darwin-x86_64"
 if [[ ${KOKORO_GFILE_DIR:-} ]] && [[ -f ${KOKORO_GFILE_DIR}/${KOKORO_GFILE_BAZEL_BIN} ]]; then
   BAZEL_BIN="${KOKORO_GFILE_DIR}/${KOKORO_GFILE_BAZEL_BIN}"
   chmod +x ${BAZEL_BIN}
diff --git a/create_lts.py b/create_lts.py
index a98c76b..302812a 100755
--- a/create_lts.py
+++ b/create_lts.py
@@ -108,11 +108,16 @@
           'project(absl LANGUAGES CXX)':
               'project(absl LANGUAGES CXX VERSION {})'.format(datestamp)
       })
-  # Set the SOVERSION to YYYYMMDD.0.0 - The first 0 means we only have
-  # ABI compatible changes, and the second 0 means we can increment it
-  # to mark changes as ABI-compatible, for patch releases.
-  ReplaceStringsInFile('CMake/AbseilHelpers.cmake',
-                       {'SOVERSION 0': 'SOVERSION "{}.0.0"'.format(datestamp)})
+  # Set the SOVERSION to YYMM.0.0 - The first 0 means we only have ABI
+  # compatible changes, and the second 0 means we can increment it to
+  # mark changes as ABI-compatible, for patch releases.  Note that we
+  # only use the last two digits of the year and the month because the
+  # MacOS linker requires the first part of the SOVERSION to fit into
+  # 16 bits.
+  # https://www.sicpers.info/2013/03/how-to-version-a-mach-o-library/
+  ReplaceStringsInFile(
+      'CMake/AbseilHelpers.cmake',
+      {'SOVERSION 0': 'SOVERSION "{}.0.0"'.format(datestamp[2:6])})
   StripContentBetweenTags('CMakeLists.txt', '# absl:lts-remove-begin',
                           '# absl:lts-remove-end')