diff --git a/absl/base/config.h b/absl/base/config.h
index 373aa0c..cd7781c 100644
--- a/absl/base/config.h
+++ b/absl/base/config.h
@@ -414,7 +414,7 @@
     defined(_AIX) || defined(__ros__) || defined(__native_client__) ||    \
     defined(__asmjs__) || defined(__wasm__) || defined(__Fuchsia__) ||    \
     defined(__sun) || defined(__ASYLO__) || defined(__myriad2__) ||       \
-    defined(__HAIKU__)
+    defined(__HAIKU__) || defined(__OpenBSD__) || defined(__NetBSD__)
 #define ABSL_HAVE_MMAP 1
 #endif
 
@@ -425,7 +425,8 @@
 #ifdef ABSL_HAVE_PTHREAD_GETSCHEDPARAM
 #error ABSL_HAVE_PTHREAD_GETSCHEDPARAM cannot be directly set
 #elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \
-    defined(_AIX) || defined(__ros__)
+    defined(_AIX) || defined(__ros__) || defined(__OpenBSD__) || \
+    defined(__NetBSD__)
 #define ABSL_HAVE_PTHREAD_GETSCHEDPARAM 1
 #endif
 
diff --git a/absl/base/internal/raw_logging.cc b/absl/base/internal/raw_logging.cc
index 074e026..509d746 100644
--- a/absl/base/internal/raw_logging.cc
+++ b/absl/base/internal/raw_logging.cc
@@ -36,8 +36,8 @@
 // This preprocessor token is also defined in raw_io.cc.  If you need to copy
 // this, consider moving both to config.h instead.
 #if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \
-    defined(__Fuchsia__) || defined(__native_client__) || \
-    defined(__EMSCRIPTEN__) || defined(__ASYLO__)
+    defined(__Fuchsia__) || defined(__native_client__) ||               \
+    defined(__OpenBSD__) || defined(__EMSCRIPTEN__) || defined(__ASYLO__)
 
 #include <unistd.h>
 
@@ -50,7 +50,8 @@
 // ABSL_HAVE_SYSCALL_WRITE is defined when the platform provides the syscall
 //   syscall(SYS_write, /*int*/ fd, /*char* */ buf, /*size_t*/ len);
 // for low level operations that want to avoid libc.
-#if (defined(__linux__) || defined(__FreeBSD__)) && !defined(__ANDROID__)
+#if (defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__)) && \
+    !defined(__ANDROID__)
 #include <sys/syscall.h>
 #define ABSL_HAVE_SYSCALL_WRITE 1
 #define ABSL_LOW_LEVEL_WRITE_SUPPORTED 1
diff --git a/absl/debugging/internal/elf_mem_image.cc b/absl/debugging/internal/elf_mem_image.cc
index 29a2818..a9d6671 100644
--- a/absl/debugging/internal/elf_mem_image.cc
+++ b/absl/debugging/internal/elf_mem_image.cc
@@ -351,7 +351,11 @@
   const ElfW(Versym) *version_symbol = image->GetVersym(index_);
   ABSL_RAW_CHECK(symbol && version_symbol, "");
   const char *const symbol_name = image->GetDynstr(symbol->st_name);
+#if defined(__NetBSD__)
+  const int version_index = version_symbol->vs_vers & VERSYM_VERSION;
+#else
   const ElfW(Versym) version_index = version_symbol[0] & VERSYM_VERSION;
+#endif
   const ElfW(Verdef) *version_definition = nullptr;
   const char *version_name = "";
   if (symbol->st_shndx == SHN_UNDEF) {
diff --git a/absl/debugging/internal/elf_mem_image.h b/absl/debugging/internal/elf_mem_image.h
index a894bd4..be20256 100644
--- a/absl/debugging/internal/elf_mem_image.h
+++ b/absl/debugging/internal/elf_mem_image.h
@@ -31,8 +31,8 @@
 #error ABSL_HAVE_ELF_MEM_IMAGE cannot be directly set
 #endif
 
-#if defined(__ELF__) && !defined(__native_client__) && !defined(__asmjs__) && \
-    !defined(__wasm__)
+#if defined(__ELF__) && !defined(__OpenBSD__) && \
+    !defined(__native_client__) && !defined(__asmjs__) && !defined(__wasm__)
 #define ABSL_HAVE_ELF_MEM_IMAGE 1
 #endif
 
diff --git a/absl/debugging/internal/examine_stack.cc b/absl/debugging/internal/examine_stack.cc
index 2fbfea8..81d216f 100644
--- a/absl/debugging/internal/examine_stack.cc
+++ b/absl/debugging/internal/examine_stack.cc
@@ -37,6 +37,16 @@
 ABSL_NAMESPACE_BEGIN
 namespace debugging_internal {
 
+namespace {
+ABSL_CONST_INIT SymbolizeUrlEmitter debug_stack_trace_hook = nullptr;
+}  // namespace
+
+void RegisterDebugStackTraceHook(SymbolizeUrlEmitter hook) {
+  debug_stack_trace_hook = hook;
+}
+
+SymbolizeUrlEmitter GetDebugStackTraceHook() { return debug_stack_trace_hook; }
+
 // Returns the program counter from signal context, nullptr if
 // unknown. vuc is a ucontext_t*. We use void* to avoid the use of
 // ucontext_t on non-POSIX systems.
diff --git a/absl/debugging/internal/examine_stack.h b/absl/debugging/internal/examine_stack.h
index 3933691..61f0056 100644
--- a/absl/debugging/internal/examine_stack.h
+++ b/absl/debugging/internal/examine_stack.h
@@ -23,6 +23,21 @@
 ABSL_NAMESPACE_BEGIN
 namespace debugging_internal {
 
+// Type of function used for printing in stack trace dumping, etc.
+// We avoid closures to keep things simple.
+typedef void OutputWriter(const char*, void*);
+
+// RegisterDebugStackTraceHook() allows to register a single routine
+// `hook` that is called each time DumpStackTrace() is called.
+// `hook` may be called from a signal handler.
+typedef void (*SymbolizeUrlEmitter)(void* const stack[], int depth,
+                                    OutputWriter writer, void* writer_arg);
+
+// Registration of SymbolizeUrlEmitter for use inside of a signal handler.
+// This is inherently unsafe and must be signal safe code.
+void RegisterDebugStackTraceHook(SymbolizeUrlEmitter hook);
+SymbolizeUrlEmitter GetDebugStackTraceHook();
+
 // Returns the program counter from signal context, or nullptr if
 // unknown. `vuc` is a ucontext_t*. We use void* to avoid the use of
 // ucontext_t on non-POSIX systems.
diff --git a/absl/debugging/internal/vdso_support.cc b/absl/debugging/internal/vdso_support.cc
index 8a015d5..c655cf4 100644
--- a/absl/debugging/internal/vdso_support.cc
+++ b/absl/debugging/internal/vdso_support.cc
@@ -50,6 +50,10 @@
 #define AT_SYSINFO_EHDR 33  // for crosstoolv10
 #endif
 
+#if defined(__NetBSD__)
+using Elf32_auxv_t = Aux32Info;
+using Elf64_auxv_t = Aux64Info;
+#endif
 #if defined(__FreeBSD__)
 #if defined(__ELF_WORD_SIZE) && __ELF_WORD_SIZE == 64
 using Elf64_auxv_t = Elf64_Auxinfo;
@@ -106,8 +110,13 @@
     ElfW(auxv_t) aux;
     while (read(fd, &aux, sizeof(aux)) == sizeof(aux)) {
       if (aux.a_type == AT_SYSINFO_EHDR) {
+#if defined(__NetBSD__)
+        vdso_base_.store(reinterpret_cast<void *>(aux.a_v),
+                         std::memory_order_relaxed);
+#else
         vdso_base_.store(reinterpret_cast<void *>(aux.a_un.a_val),
                          std::memory_order_relaxed);
+#endif
         break;
       }
     }
diff --git a/absl/flags/declare.h b/absl/flags/declare.h
index a791b66..d1437bb 100644
--- a/absl/flags/declare.h
+++ b/absl/flags/declare.h
@@ -60,7 +60,11 @@
 // The ABSL_DECLARE_FLAG(type, name) macro expands to:
 //
 //   extern absl::Flag<type> FLAGS_name;
-#define ABSL_DECLARE_FLAG(type, name)                        \
+#define ABSL_DECLARE_FLAG(type, name) ABSL_DECLARE_FLAG_INTERNAL(type, name)
+
+// Internal implementation of ABSL_DECLARE_FLAG to allow macro expansion of its
+// arguments. Clients must use ABSL_DECLARE_FLAG instead.
+#define ABSL_DECLARE_FLAG_INTERNAL(type, name)               \
   extern absl::Flag<type> FLAGS_##name;                      \
   namespace absl /* block flags in namespaces */ {}          \
   /* second redeclaration is to allow applying attributes */ \
diff --git a/absl/flags/flag.h b/absl/flags/flag.h
index 5010608..d2750b3 100644
--- a/absl/flags/flag.h
+++ b/absl/flags/flag.h
@@ -163,7 +163,6 @@
 // Note: do not construct objects of type `absl::Flag<T>` directly. Only use the
 // `ABSL_FLAG()` macro for such construction.
 #define ABSL_FLAG(Type, name, default_value, help) \
-  extern ::absl::Flag<Type> FLAGS_##name;          \
   ABSL_FLAG_IMPL(Type, name, default_value, help)
 
 // ABSL_FLAG().OnUpdate()
@@ -266,6 +265,7 @@
 // global name for FLAGS_no<flag_name> symbol, thus preventing the possibility
 // of defining two flags with names foo and nofoo.
 #define ABSL_FLAG_IMPL(Type, name, default_value, help)                       \
+  extern ::absl::Flag<Type> FLAGS_##name;                                     \
   namespace absl /* block flags in namespaces */ {}                           \
   ABSL_FLAG_IMPL_DECLARE_DEF_VAL_WRAPPER(name, Type, default_value)           \
   ABSL_FLAG_IMPL_DECLARE_HELP_WRAPPER(name, help)                             \
diff --git a/absl/flags/flag_test.cc b/absl/flags/flag_test.cc
index 6e974a5..ced332d 100644
--- a/absl/flags/flag_test.cc
+++ b/absl/flags/flag_test.cc
@@ -977,3 +977,16 @@
   value = absl::GetFlag(FLAGS_test_enum_wrapper_flag);
   EXPECT_EQ(value.e, B);
 }
+
+// This is a compile test to ensure macros are expanded within ABSL_FLAG and
+// ABSL_DECLARE_FLAG.
+#define FLAG_NAME_MACRO(name) prefix_ ## name
+ABSL_DECLARE_FLAG(int, FLAG_NAME_MACRO(test_macro_named_flag));
+ABSL_FLAG(int, FLAG_NAME_MACRO(test_macro_named_flag), 0,
+          "Testing macro expansion within ABSL_FLAG");
+
+TEST_F(FlagTest, MacroWithinAbslFlag) {
+  EXPECT_EQ(absl::GetFlag(FLAGS_prefix_test_macro_named_flag), 0);
+  absl::SetFlag(&FLAGS_prefix_test_macro_named_flag, 1);
+  EXPECT_EQ(absl::GetFlag(FLAGS_prefix_test_macro_named_flag), 1);
+}
diff --git a/absl/hash/hash_test.cc b/absl/hash/hash_test.cc
index 39ff8f5..ffa45e6 100644
--- a/absl/hash/hash_test.cc
+++ b/absl/hash/hash_test.cc
@@ -185,6 +185,8 @@
 
 TEST(HashValueTest, Pointer) {
   EXPECT_TRUE((is_hashable<int*>::value));
+  EXPECT_TRUE((is_hashable<int(*)(char, float)>::value));
+  EXPECT_TRUE((is_hashable<void(*)(int, int, ...)>::value));
 
   int i;
   int* ptr = &i;
@@ -224,6 +226,85 @@
   }
 }
 
+TEST(HashValueTest, PointerToMember) {
+  struct Bass {
+    void q() {}
+  };
+
+  struct A : Bass {
+    virtual ~A() = default;
+    virtual void vfa() {}
+
+    static auto pq() -> void (A::*)() { return &A::q; }
+  };
+
+  struct B : Bass {
+    virtual ~B() = default;
+    virtual void vfb() {}
+
+    static auto pq() -> void (B::*)() { return &B::q; }
+  };
+
+  struct Foo : A, B {
+    void f1() {}
+    void f2() const {}
+
+    int g1() & { return 0; }
+    int g2() const & { return 0; }
+    int g3() && { return 0; }
+    int g4() const && { return 0; }
+
+    int h1() & { return 0; }
+    int h2() const & { return 0; }
+    int h3() && { return 0; }
+    int h4() const && { return 0; }
+
+    int a;
+    int b;
+
+    const int c = 11;
+    const int d = 22;
+  };
+
+  EXPECT_TRUE((is_hashable<float Foo::*>::value));
+  EXPECT_TRUE((is_hashable<double (Foo::*)(int, int)&&>::value));
+
+  EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(
+      std::make_tuple(&Foo::a, &Foo::b, static_cast<int Foo::*>(nullptr))));
+
+  EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(
+      std::make_tuple(&Foo::c, &Foo::d, static_cast<const int Foo::*>(nullptr),
+                      &Foo::a, &Foo::b)));
+
+  EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple(
+      &Foo::f1, static_cast<void (Foo::*)()>(nullptr))));
+
+  EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple(
+      &Foo::f2, static_cast<void (Foo::*)() const>(nullptr))));
+
+  EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple(
+      &Foo::g1, &Foo::h1, static_cast<int (Foo::*)() &>(nullptr))));
+
+  EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple(
+      &Foo::g2, &Foo::h2, static_cast<int (Foo::*)() const &>(nullptr))));
+
+  EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple(
+      &Foo::g3, &Foo::h3, static_cast<int (Foo::*)() &&>(nullptr))));
+
+  EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple(
+      &Foo::g4, &Foo::h4, static_cast<int (Foo::*)() const &&>(nullptr))));
+
+  EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(
+      std::make_tuple(static_cast<void (Foo::*)()>(&Foo::vfa),
+                      static_cast<void (Foo::*)()>(&Foo::vfb),
+                      static_cast<void (Foo::*)()>(nullptr))));
+
+  EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(
+      std::make_tuple(static_cast<void (Foo::*)()>(Foo::A::pq()),
+                      static_cast<void (Foo::*)()>(Foo::B::pq()),
+                      static_cast<void (Foo::*)()>(nullptr))));
+}
+
 TEST(HashValueTest, PairAndTuple) {
   EXPECT_TRUE((is_hashable<std::pair<int, int>>::value));
   EXPECT_TRUE((is_hashable<std::pair<const int&, const int&>>::value));
diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h
index a424e01..f810333 100644
--- a/absl/hash/internal/hash.h
+++ b/absl/hash/internal/hash.h
@@ -421,6 +421,39 @@
   return H::combine(std::move(hash_state), static_cast<void*>(nullptr));
 }
 
+// AbslHashValue() for hashing pointers-to-member
+template <typename H, typename T, typename C>
+H AbslHashValue(H hash_state, T C::* ptr) {
+  auto salient_ptm_size = [](std::size_t n) -> std::size_t {
+#if defined(_MSC_VER)
+    // Pointers-to-member-function on MSVC consist of one pointer plus 0, 1, 2,
+    // or 3 ints. In 64-bit mode, they are 8-byte aligned and thus can contain
+    // padding (namely when they have 1 or 3 ints). The value below is a lower
+    // bound on the number of salient, non-padding bytes that we use for
+    // hashing.
+    if (alignof(T C::*) == alignof(int)) {
+      // No padding when all subobjects have the same size as the total
+      // alignment. This happens in 32-bit mode.
+      return n;
+    } else {
+      // Padding for 1 int (size 16) or 3 ints (size 24).
+      // With 2 ints, the size is 16 with no padding, which we pessimize.
+      return n == 24 ? 20 : n == 16 ? 12 : n;
+    }
+#else
+    // On other platforms, we assume that pointers-to-members do not have
+    // padding.
+#ifdef __cpp_lib_has_unique_object_representations
+    static_assert(std::has_unique_object_representations_v<T C::*>);
+#endif  // __cpp_lib_has_unique_object_representations
+    return n;
+#endif
+  };
+  return H::combine_contiguous(std::move(hash_state),
+                               reinterpret_cast<unsigned char*>(&ptr),
+                               salient_ptm_size(sizeof ptr));
+}
+
 // -----------------------------------------------------------------------------
 // AbslHashValue for Composite Types
 // -----------------------------------------------------------------------------
diff --git a/absl/random/bit_gen_ref.h b/absl/random/bit_gen_ref.h
index 9555460..e475221 100644
--- a/absl/random/bit_gen_ref.h
+++ b/absl/random/bit_gen_ref.h
@@ -24,6 +24,10 @@
 #ifndef ABSL_RANDOM_BIT_GEN_REF_H_
 #define ABSL_RANDOM_BIT_GEN_REF_H_
 
+#include <limits>
+#include <type_traits>
+#include <utility>
+
 #include "absl/base/internal/fast_type_id.h"
 #include "absl/base/macros.h"
 #include "absl/meta/type_traits.h"
diff --git a/absl/random/internal/chi_square.cc b/absl/random/internal/chi_square.cc
index 640d48c..fbe0173 100644
--- a/absl/random/internal/chi_square.cc
+++ b/absl/random/internal/chi_square.cc
@@ -125,7 +125,8 @@
     const double variance = 2.0 / (9 * dof);
     // Cannot use this method if the variance is 0.
     if (variance != 0) {
-      return std::pow(z * std::sqrt(variance) + mean, 3.0) * dof;
+      double term = z * std::sqrt(variance) + mean;
+      return dof * (term * term * term);
     }
   }
 
diff --git a/absl/random/internal/distribution_caller.h b/absl/random/internal/distribution_caller.h
index f1ad5cc..0f162a4 100644
--- a/absl/random/internal/distribution_caller.h
+++ b/absl/random/internal/distribution_caller.h
@@ -18,6 +18,7 @@
 #define ABSL_RANDOM_INTERNAL_DISTRIBUTION_CALLER_H_
 
 #include <utility>
+#include <type_traits>
 
 #include "absl/base/config.h"
 #include "absl/base/internal/fast_type_id.h"
diff --git a/absl/random/internal/mock_helpers.h b/absl/random/internal/mock_helpers.h
index 9d6ab21..882b051 100644
--- a/absl/random/internal/mock_helpers.h
+++ b/absl/random/internal/mock_helpers.h
@@ -18,6 +18,7 @@
 
 #include <tuple>
 #include <type_traits>
+#include <utility>
 
 #include "absl/base/internal/fast_type_id.h"
 #include "absl/types/optional.h"
diff --git a/absl/strings/cord.cc b/absl/strings/cord.cc
index b65dc58..c6ec1ec 100644
--- a/absl/strings/cord.cc
+++ b/absl/strings/cord.cc
@@ -87,30 +87,6 @@
   return node;
 }
 
-// Create a concatenation of the specified nodes.
-// Does not change the refcounts of "left" and "right".
-// The returned node has a refcount of 1.
-static CordRep* RawConcat(CordRep* left, CordRep* right) {
-  // Avoid making degenerate concat nodes (one child is empty)
-  if (left == nullptr) return right;
-  if (right == nullptr) return left;
-  if (left->length == 0) {
-    CordRep::Unref(left);
-    return right;
-  }
-  if (right->length == 0) {
-    CordRep::Unref(right);
-    return left;
-  }
-  ABSL_INTERNAL_LOG(FATAL, "CordRepConcat is no longer supported");
-  return nullptr;
-}
-
-static CordRep* Concat(CordRep* left, CordRep* right) {
-  CordRep* rep = RawConcat(left, right);
-  return VerifyTree(rep);
-}
-
 static CordRepFlat* CreateFlat(const char* data, size_t length,
                                size_t alloc_hint) {
   CordRepFlat* flat = CordRepFlat::New(length + alloc_hint);
@@ -608,68 +584,6 @@
 
 template void Cord::Prepend(std::string&& src);
 
-static CordRep* RemovePrefixFrom(CordRep* node, size_t n) {
-  if (n >= node->length) return nullptr;
-  if (n == 0) return CordRep::Ref(node);
-  absl::InlinedVector<CordRep*, kInlinedVectorSize> rhs_stack;
-
-  assert(!node->IsCrc());
-  assert(n <= node->length);
-
-  if (n == 0) {
-    CordRep::Ref(node);
-  } else {
-    size_t start = n;
-    size_t len = node->length - n;
-    if (node->IsSubstring()) {
-      // Consider in-place update of node, similar to in RemoveSuffixFrom().
-      start += node->substring()->start;
-      node = node->substring()->child;
-    }
-    node = CordRepSubstring::Create(CordRep::Ref(node), start, len);
-  }
-  while (!rhs_stack.empty()) {
-    node = Concat(node, CordRep::Ref(rhs_stack.back()));
-    rhs_stack.pop_back();
-  }
-  return node;
-}
-
-// RemoveSuffixFrom() is very similar to RemovePrefixFrom(), with the
-// exception that removing a suffix has an optimization where a node may be
-// edited in place iff that node and all its ancestors have a refcount of 1.
-static CordRep* RemoveSuffixFrom(CordRep* node, size_t n) {
-  if (n >= node->length) return nullptr;
-  if (n == 0) return CordRep::Ref(node);
-  absl::InlinedVector<CordRep*, kInlinedVectorSize> lhs_stack;
-  bool inplace_ok = node->refcount.IsOne();
-  assert(!node->IsCrc());
-
-  assert(n <= node->length);
-
-  if (n == 0) {
-    CordRep::Ref(node);
-  } else if (inplace_ok && !node->IsExternal()) {
-    // Consider making a new buffer if the current node capacity is much
-    // larger than the new length.
-    CordRep::Ref(node);
-    node->length -= n;
-  } else {
-    size_t start = 0;
-    size_t len = node->length - n;
-    if (node->IsSubstring()) {
-      start = node->substring()->start;
-      node = node->substring()->child;
-    }
-    node = CordRepSubstring::Create(CordRep::Ref(node), start, len);
-  }
-  while (!lhs_stack.empty()) {
-    node = Concat(CordRep::Ref(lhs_stack.back()), node);
-    lhs_stack.pop_back();
-  }
-  return node;
-}
-
 void Cord::RemovePrefix(size_t n) {
   ABSL_INTERNAL_CHECK(n <= size(),
                       absl::StrCat("Requested prefix size ", n,
@@ -681,14 +595,20 @@
     auto constexpr method = CordzUpdateTracker::kRemovePrefix;
     CordzUpdateScope scope(contents_.cordz_info(), method);
     tree = cord_internal::RemoveCrcNode(tree);
-    if (tree->IsBtree()) {
+    if (n >= tree->length) {
+      CordRep::Unref(tree);
+      tree = nullptr;
+    } else if (tree->IsBtree()) {
       CordRep* old = tree;
       tree = tree->btree()->SubTree(n, tree->length - n);
       CordRep::Unref(old);
+    } else if (tree->IsSubstring() && tree->refcount.IsOne()) {
+      tree->substring()->start += n;
+      tree->length -= n;
     } else {
-      CordRep* newrep = RemovePrefixFrom(tree, n);
+      CordRep* rep = CordRepSubstring::Substring(tree, n, tree->length - n);
       CordRep::Unref(tree);
-      tree = VerifyTree(newrep);
+      tree = rep;
     }
     contents_.SetTreeOrEmpty(tree, scope);
   }
@@ -705,59 +625,23 @@
     auto constexpr method = CordzUpdateTracker::kRemoveSuffix;
     CordzUpdateScope scope(contents_.cordz_info(), method);
     tree = cord_internal::RemoveCrcNode(tree);
-    if (tree->IsBtree()) {
-      tree = CordRepBtree::RemoveSuffix(tree->btree(), n);
-    } else {
-      CordRep* newrep = RemoveSuffixFrom(tree, n);
+    if (n >= tree->length) {
       CordRep::Unref(tree);
-      tree = VerifyTree(newrep);
+      tree = nullptr;
+    } else if (tree->IsBtree()) {
+      tree = CordRepBtree::RemoveSuffix(tree->btree(), n);
+    } else if (!tree->IsExternal() && tree->refcount.IsOne()) {
+      assert(tree->IsFlat() || tree->IsSubstring());
+      tree->length -= n;
+    } else {
+      CordRep* rep = CordRepSubstring::Substring(tree, 0, tree->length - n);
+      CordRep::Unref(tree);
+      tree = rep;
     }
     contents_.SetTreeOrEmpty(tree, scope);
   }
 }
 
-// Work item for NewSubRange().
-struct SubRange {
-  SubRange(CordRep* a_node, size_t a_pos, size_t a_n)
-      : node(a_node), pos(a_pos), n(a_n) {}
-  CordRep* node;  // nullptr means concat last 2 results.
-  size_t pos;
-  size_t n;
-};
-
-static CordRep* NewSubRange(CordRep* node, size_t pos, size_t n) {
-  absl::InlinedVector<CordRep*, kInlinedVectorSize> results;
-  absl::InlinedVector<SubRange, kInlinedVectorSize> todo;
-  assert(!node->IsCrc());
-  todo.push_back(SubRange(node, pos, n));
-  do {
-    const SubRange& sr = todo.back();
-    node = sr.node;
-    pos = sr.pos;
-    n = sr.n;
-    todo.pop_back();
-
-    if (node == nullptr) {
-      assert(results.size() >= 2);
-      CordRep* right = results.back();
-      results.pop_back();
-      CordRep* left = results.back();
-      results.pop_back();
-      results.push_back(Concat(left, right));
-    } else if (pos == 0 && n == node->length) {
-      results.push_back(CordRep::Ref(node));
-    } else {
-      if (node->IsSubstring()) {
-        pos += node->substring()->start;
-        node = node->substring()->child;
-      }
-      results.push_back(CordRepSubstring::Create(CordRep::Ref(node), pos, n));
-    }
-  } while (!todo.empty());
-  assert(results.size() == 1);
-  return results[0];
-}
-
 Cord Cord::Subcord(size_t pos, size_t new_size) const {
   Cord sub_cord;
   size_t length = size();
@@ -791,7 +675,7 @@
   if (tree->IsBtree()) {
     tree = tree->btree()->SubTree(pos, new_size);
   } else {
-    tree = NewSubRange(tree, pos, new_size);
+    tree = CordRepSubstring::Substring(tree, pos, new_size);
   }
   sub_cord.contents_.EmplaceTree(tree, contents_.data_,
                                  CordzUpdateTracker::kSubCord);
@@ -1140,7 +1024,7 @@
                                            : payload->flat()->Data();
   const size_t offset = current_chunk_.data() - data;
 
-  auto* tree = CordRepSubstring::Create(CordRep::Ref(payload), offset, n);
+  auto* tree = CordRepSubstring::Substring(payload, offset, n);
   subcord.contents_.EmplaceTree(VerifyTree(tree), method);
   bytes_remaining_ -= n;
   current_chunk_.remove_prefix(n);
diff --git a/absl/strings/internal/cord_internal.h b/absl/strings/internal/cord_internal.h
index ece3db1..2087ffe 100644
--- a/absl/strings/internal/cord_internal.h
+++ b/absl/strings/internal/cord_internal.h
@@ -286,6 +286,14 @@
   // form a non-empty partial sub range of `'child`, i.e.:
   // `n > 0 && n < length && n + pos <= length`
   static inline CordRepSubstring* Create(CordRep* child, size_t pos, size_t n);
+
+  // Creates a substring of `rep`. Does not adopt a reference on `rep`.
+  // Requires `IsDataEdge(rep) && n > 0 && pos + n <= rep->length`.
+  // If `n == rep->length` then this method returns `CordRep::Ref(rep)`
+  // If `rep` is a substring of a flat or external node, then this method will
+  // return a new substring of that flat or external node with `pos` adjusted
+  // with the original `start` position.
+  static inline CordRep* Substring(CordRep* rep, size_t pos, size_t n);
 };
 
 // Type for function pointer that will invoke the releaser function and also
@@ -371,6 +379,25 @@
   return rep;
 }
 
+inline CordRep* CordRepSubstring::Substring(CordRep* rep, size_t pos,
+                                            size_t n) {
+  assert(rep != nullptr);
+  assert(n != 0);
+  assert(pos < rep->length);
+  assert(n <= rep->length - pos);
+  if (n == rep->length) return CordRep::Ref(rep);
+  if (rep->IsSubstring()) {
+    pos += rep->substring()->start;
+    rep = rep->substring()->child;
+  }
+  CordRepSubstring* substr = new CordRepSubstring();
+  substr->length = n;
+  substr->tag = SUBSTRING;
+  substr->start = pos;
+  substr->child = CordRep::Ref(rep);
+  return substr;
+}
+
 inline void CordRepExternal::Delete(CordRep* rep) {
   assert(rep != nullptr && rep->IsExternal());
   auto* rep_external = static_cast<CordRepExternal*>(rep);
diff --git a/absl/time/duration_test.cc b/absl/time/duration_test.cc
index b7209e1..b7abf4b 100644
--- a/absl/time/duration_test.cc
+++ b/absl/time/duration_test.cc
@@ -349,6 +349,11 @@
 }
 
 TEST(Duration, FactoryOverloads) {
+#if defined(ABSL_SKIP_TIME_TESTS_BROKEN_ON_MSVC_OPT) && \
+    ABSL_SKIP_TIME_TESTS_BROKEN_ON_MSVC_OPT
+  GTEST_SKIP();
+#endif
+
   enum E { kOne = 1 };
 #define TEST_FACTORY_OVERLOADS(NAME)                                          \
   EXPECT_EQ(1, NAME(kOne) / NAME(kOne));                                      \
@@ -879,6 +884,11 @@
 }
 
 TEST(Duration, Addition) {
+#if defined(ABSL_SKIP_TIME_TESTS_BROKEN_ON_MSVC_OPT) && \
+    ABSL_SKIP_TIME_TESTS_BROKEN_ON_MSVC_OPT
+  GTEST_SKIP();
+#endif
+
 #define TEST_ADD_OPS(UNIT)                  \
   do {                                      \
     EXPECT_EQ(UNIT(2), UNIT(1) + UNIT(1));  \
@@ -972,6 +982,11 @@
 }
 
 TEST(Duration, AbsoluteValue) {
+#if defined(ABSL_SKIP_TIME_TESTS_BROKEN_ON_MSVC_OPT) && \
+    ABSL_SKIP_TIME_TESTS_BROKEN_ON_MSVC_OPT
+  GTEST_SKIP();
+#endif
+
   EXPECT_EQ(absl::ZeroDuration(), AbsDuration(absl::ZeroDuration()));
   EXPECT_EQ(absl::Seconds(1), AbsDuration(absl::Seconds(1)));
   EXPECT_EQ(absl::Seconds(1), AbsDuration(absl::Seconds(-1)));
@@ -989,6 +1004,11 @@
 }
 
 TEST(Duration, Multiplication) {
+#if defined(ABSL_SKIP_TIME_TESTS_BROKEN_ON_MSVC_OPT) && \
+    ABSL_SKIP_TIME_TESTS_BROKEN_ON_MSVC_OPT
+  GTEST_SKIP();
+#endif
+
 #define TEST_MUL_OPS(UNIT)                                    \
   do {                                                        \
     EXPECT_EQ(UNIT(5), UNIT(2) * 2.5);                        \
@@ -1241,6 +1261,11 @@
 }
 
 TEST(Duration, TruncConversions) {
+#if defined(ABSL_SKIP_TIME_TESTS_BROKEN_ON_MSVC_OPT) && \
+    ABSL_SKIP_TIME_TESTS_BROKEN_ON_MSVC_OPT
+  GTEST_SKIP();
+#endif
+
   // Tests ToTimespec()/DurationFromTimespec()
   const struct {
     absl::Duration d;
@@ -1537,6 +1562,11 @@
 }
 
 TEST(Duration, FormatDuration) {
+#if defined(ABSL_SKIP_TIME_TESTS_BROKEN_ON_MSVC_OPT) && \
+    ABSL_SKIP_TIME_TESTS_BROKEN_ON_MSVC_OPT
+  GTEST_SKIP();
+#endif
+
   // Example from Go's docs.
   EXPECT_EQ("72h3m0.5s",
             absl::FormatDuration(absl::Hours(72) + absl::Minutes(3) +
@@ -1671,6 +1701,11 @@
 }
 
 TEST(Duration, ParseDuration) {
+#if defined(ABSL_SKIP_TIME_TESTS_BROKEN_ON_MSVC_OPT) && \
+    ABSL_SKIP_TIME_TESTS_BROKEN_ON_MSVC_OPT
+  GTEST_SKIP();
+#endif
+
   absl::Duration d;
 
   // No specified unit. Should only work for zero and infinity.
diff --git a/absl/time/time_test.cc b/absl/time/time_test.cc
index cde9423..d235e9a 100644
--- a/absl/time/time_test.cc
+++ b/absl/time/time_test.cc
@@ -377,6 +377,11 @@
 }
 
 TEST(Time, RoundtripConversion) {
+#if defined(ABSL_SKIP_TIME_TESTS_BROKEN_ON_MSVC_OPT) && \
+    ABSL_SKIP_TIME_TESTS_BROKEN_ON_MSVC_OPT
+  GTEST_SKIP();
+#endif
+
 #define TEST_CONVERSION_ROUND_TRIP(SOURCE, FROM, TO, MATCHER) \
   EXPECT_THAT(TO(FROM(SOURCE)), MATCHER(SOURCE))
 
@@ -558,6 +563,11 @@
 }
 
 TEST(Time, ToChronoTime) {
+#if defined(ABSL_SKIP_TIME_TESTS_BROKEN_ON_MSVC_OPT) && \
+    ABSL_SKIP_TIME_TESTS_BROKEN_ON_MSVC_OPT
+  GTEST_SKIP();
+#endif
+
   EXPECT_EQ(std::chrono::system_clock::from_time_t(-1),
             absl::ToChronoTime(absl::FromTimeT(-1)));
   EXPECT_EQ(std::chrono::system_clock::from_time_t(0),
diff --git a/absl/types/optional.h b/absl/types/optional.h
index 61540cf..134b2af 100644
--- a/absl/types/optional.h
+++ b/absl/types/optional.h
@@ -282,15 +282,16 @@
   optional& operator=(optional&& src) = default;
 
   // Value assignment operators
-  template <
-      typename U = T,
-      typename = typename std::enable_if<absl::conjunction<
-          absl::negation<
-              std::is_same<optional<T>, typename std::decay<U>::type>>,
-          absl::negation<
-              absl::conjunction<std::is_scalar<T>,
-                                std::is_same<T, typename std::decay<U>::type>>>,
-          std::is_constructible<T, U>, std::is_assignable<T&, U>>::value>::type>
+  template <typename U = T,
+            int&...,  // Workaround an internal compiler error in GCC 5 to 10.
+            typename = typename std::enable_if<absl::conjunction<
+                absl::negation<
+                    std::is_same<optional<T>, typename std::decay<U>::type> >,
+                absl::negation<absl::conjunction<
+                    std::is_scalar<T>,
+                    std::is_same<T, typename std::decay<U>::type> > >,
+                std::is_constructible<T, U>,
+                std::is_assignable<T&, U> >::value>::type>
   optional& operator=(U&& v) {
     this->assign(std::forward<U>(v));
     return *this;
@@ -298,13 +299,14 @@
 
   template <
       typename U,
+      int&...,  // Workaround an internal compiler error in GCC 5 to 10.
       typename = typename std::enable_if<absl::conjunction<
-          absl::negation<std::is_same<T, U>>,
+          absl::negation<std::is_same<T, U> >,
           std::is_constructible<T, const U&>, std::is_assignable<T&, const U&>,
           absl::negation<
               optional_internal::
                   is_constructible_convertible_assignable_from_optional<
-                      T, U>>>::value>::type>
+                      T, U> > >::value>::type>
   optional& operator=(const optional<U>& rhs) {
     if (rhs) {
       this->assign(*rhs);
@@ -315,13 +317,14 @@
   }
 
   template <typename U,
+            int&...,  // Workaround an internal compiler error in GCC 5 to 10.
             typename = typename std::enable_if<absl::conjunction<
-                absl::negation<std::is_same<T, U>>, std::is_constructible<T, U>,
-                std::is_assignable<T&, U>,
+                absl::negation<std::is_same<T, U> >,
+                std::is_constructible<T, U>, std::is_assignable<T&, U>,
                 absl::negation<
                     optional_internal::
                         is_constructible_convertible_assignable_from_optional<
-                            T, U>>>::value>::type>
+                            T, U> > >::value>::type>
   optional& operator=(optional<U>&& rhs) {
     if (rhs) {
       this->assign(std::move(*rhs));
diff --git a/absl/types/optional_test.cc b/absl/types/optional_test.cc
index 7ef142c..1846e69 100644
--- a/absl/types/optional_test.cc
+++ b/absl/types/optional_test.cc
@@ -27,6 +27,32 @@
 #include "absl/meta/type_traits.h"
 #include "absl/strings/string_view.h"
 
+// The following types help test an internal compiler error in GCC5 though
+// GCC10. The case OptionalTest.InternalCompilerErrorInGcc5ToGcc10 crashes the
+// compiler without a workaround. This test case should remain at the beginning
+// of the file as the internal compiler error is sensitive to other constructs
+// in this file.
+template <class T, class...>
+using GccIceHelper1 = T;
+template <typename T>
+struct GccIceHelper2 {};
+template <typename T>
+class GccIce {
+  template <typename U,
+            typename SecondTemplateArgHasToExistForSomeReason = void,
+            typename DependentType = void,
+            typename = std::is_assignable<GccIceHelper1<T, DependentType>&, U>>
+  GccIce& operator=(GccIceHelper2<U> const&) {}
+};
+
+TEST(OptionalTest, InternalCompilerErrorInGcc5ToGcc10) {
+  GccIce<int> instantiate_ice_with_same_type_as_optional;
+  static_cast<void>(instantiate_ice_with_same_type_as_optional);
+  absl::optional<int> val1;
+  absl::optional<int> val2;
+  val1 = val2;
+}
+
 struct Hashable {};
 
 namespace std {