Export of internal Abseil changes

--
6cfac39ea1266f01f195de5eb4c9a6fc9ea9b20a by Matt Kulukundis <kfm@google.com>:

Fix a typo

PiperOrigin-RevId: 366174890

--
6ee8c58647aef171d394e59fa06f9bf8cd0306ec by Derek Mauro <dmauro@google.com>:

Adds `ABSL_ATTRIBUTE_LIFETIME_BOUND` and applies it to the
`const std::string&` constructor of `absl::string_view`.

Compilers that support this attribute will emit a warning
if the parameter does not have sufficient lifetime.

PiperOrigin-RevId: 366027738

--
b944427d96e4b436b8fa0fe396c2a1118dbbbd13 by Abseil Team <absl-team@google.com>:

Calls to `ResetToEmpty()` from `ClearSlow` use ~3% of the time in assignment. However, `ClearSlow()` is only used in contexts where `data_` is immediately reassigned.

Rename `ClearSlow()` into `UnrefTree()` and remove `data_` resetting.

PiperOrigin-RevId: 365977213

--
7428b3147a5672c8bb55649efa3a1cfe19b52a8b by Abseil Team <absl-team@google.com>:

Fix CordRepRing diabolical growth

The 'Mutable' function in CordRepRing was over-eager in doubling capacity, which lead to 'ludicrous' growth in the diabolical test case as added to cord_test. This CL fixes the doubling for growing shared reps, and tempers CordRepRing growth for non shared capacity to 1.5 instead of 2, which is more inline with a conservative growth we also have in tree cord.

After this change, CordRepRing no longer swamps the heap into the shadow realm, and is in effect reducing the memory used compared to the tree implementation. With a diabolical 5000 bytes growth pattern:

Tree cord: 1523520 bytes
Ring cord:  274232 bytes

PiperOrigin-RevId: 365915857

--
f24d4aee48b03c5a7980664df903f947cbb198e8 by Andy Getzendanner <durandal@google.com>:

Import of CCTZ from GitHub.

PiperOrigin-RevId: 365873932
GitOrigin-RevId: 6cfac39ea1266f01f195de5eb4c9a6fc9ea9b20a
Change-Id: I9737aa215ac732c9785a1d0032c77aba62330f12
diff --git a/absl/base/attributes.h b/absl/base/attributes.h
index 325e2f8..294e5d0 100644
--- a/absl/base/attributes.h
+++ b/absl/base/attributes.h
@@ -706,4 +706,26 @@
 #define ABSL_ATTRIBUTE_PURE_FUNCTION
 #endif
 
+// ABSL_ATTRIBUTE_LIFETIME_BOUND indicates that a resource owned by a function
+// parameter or implicit object parameter is retained by the return value of the
+// annotated function (or, for a parameter of a constructor, in the value of the
+// constructed object). This attribute causes warnings to be produced if a
+// temporary object does not live long enough.
+//
+// When applied to a reference parameter, the referenced object is assumed to be
+// retained by the return value of the function. When applied to a non-reference
+// parameter (for example, a pointer or a class type), all temporaries
+// referenced by the parameter are assumed to be retained by the return value of
+// the function.
+//
+// See also the upstream documentation:
+// https://clang.llvm.org/docs/AttributeReference.html#lifetimebound
+#if ABSL_HAVE_CPP_ATTRIBUTE(clang::lifetimebound)
+#define ABSL_ATTRIBUTE_LIFETIME_BOUND [[clang::lifetimebound]]
+#elif ABSL_HAVE_ATTRIBUTE(lifetimebound)
+#define ABSL_ATTRIBUTE_LIFETIME_BOUND __attribute__((lifetimebound))
+#else
+#define ABSL_ATTRIBUTE_LIFETIME_BOUND
+#endif
+
 #endif  // ABSL_BASE_ATTRIBUTES_H_
diff --git a/absl/hash/internal/wyhash.h b/absl/hash/internal/wyhash.h
index 4aff4e9..2b534b4 100644
--- a/absl/hash/internal/wyhash.h
+++ b/absl/hash/internal/wyhash.h
@@ -36,7 +36,7 @@
 // integers are hashed into the result.
 //
 // To allow all hashable types (including string_view and Span) to depend on
-// this algoritm, we keep the API low-level, with as few dependencies as
+// this algorithm, we keep the API low-level, with as few dependencies as
 // possible.
 uint64_t Wyhash(const void* data, size_t len, uint64_t seed,
                 const uint64_t salt[5]);
diff --git a/absl/strings/cord.cc b/absl/strings/cord.cc
index 1c03a61..1aea396 100644
--- a/absl/strings/cord.cc
+++ b/absl/strings/cord.cc
@@ -491,7 +491,7 @@
 }
 
 void Cord::InlineRep::AssignSlow(const Cord::InlineRep& src) {
-  ClearSlow();
+  UnrefTree();
 
   data_ = src.data_;
   if (is_tree()) {
@@ -501,11 +501,10 @@
   }
 }
 
-void Cord::InlineRep::ClearSlow() {
+void Cord::InlineRep::UnrefTree() {
   if (is_tree()) {
     CordRep::Unref(tree());
   }
-  ResetToEmpty();
 }
 
 // --------------------------------------------------------------------
diff --git a/absl/strings/cord.h b/absl/strings/cord.h
index fa9cb91..cb2ffc5 100644
--- a/absl/strings/cord.h
+++ b/absl/strings/cord.h
@@ -776,8 +776,8 @@
     friend class Cord;
 
     void AssignSlow(const InlineRep& src);
-    // Unrefs the tree, stops profiling, and zeroes the contents
-    void ClearSlow();
+    // Unrefs the tree and stops profiling.
+    void UnrefTree();
 
     void ResetToEmpty() { data_ = {}; }
 
@@ -966,7 +966,7 @@
 inline Cord::InlineRep& Cord::InlineRep::operator=(
     Cord::InlineRep&& src) noexcept {
   if (is_tree()) {
-    ClearSlow();
+    UnrefTree();
   }
   data_ = src.data_;
   src.ResetToEmpty();
diff --git a/absl/strings/cord_test.cc b/absl/strings/cord_test.cc
index fb67341..710a1b4 100644
--- a/absl/strings/cord_test.cc
+++ b/absl/strings/cord_test.cc
@@ -1316,6 +1316,26 @@
   EXPECT_EQ(s2.size(), size + 1);
 }
 
+TEST(Cord, DiabolicalGrowth) {
+  // This test exercises a diabolical Append(<one char>) on a cord, making the
+  // cord shared before each Append call resulting in a terribly fragmented
+  // resulting cord.
+  // TODO(b/183983616): Apply some minimum compaction when copying a shared
+  // source cord into a mutable copy for updates in CordRepRing.
+  RandomEngine rng(testing::GTEST_FLAG(random_seed));
+  const std::string expected = RandomLowercaseString(&rng, 5000);
+  absl::Cord cord;
+  for (char c : expected) {
+    absl::Cord shared(cord);
+    cord.Append(absl::string_view(&c, 1));
+  }
+  std::string value;
+  absl::CopyCordToString(cord, &value);
+  EXPECT_EQ(value, expected);
+  ABSL_RAW_LOG(INFO, "Diabolical size allocated = %zu",
+               cord.EstimatedMemoryUsage());
+}
+
 TEST(MakeFragmentedCord, MakeFragmentedCordFromInitializerList) {
   absl::Cord fragmented =
       absl::MakeFragmentedCord({"A ", "fragmented ", "Cord"});
diff --git a/absl/strings/internal/cord_rep_ring.cc b/absl/strings/internal/cord_rep_ring.cc
index 4d31d1d..cb95b19 100644
--- a/absl/strings/internal/cord_rep_ring.cc
+++ b/absl/strings/internal/cord_rep_ring.cc
@@ -400,10 +400,11 @@
   // Get current number of entries, and check for max capacity.
   size_t entries = rep->entries();
 
-  size_t min_extra = (std::max)(extra, rep->capacity() * 2 - entries);
   if (!rep->refcount.IsOne()) {
-    return Copy(rep, rep->head(), rep->tail(), min_extra);
+    return Copy(rep, rep->head(), rep->tail(), extra);
   } else if (entries + extra > rep->capacity()) {
+    const size_t min_grow = rep->capacity() + rep->capacity() / 2;
+    const size_t min_extra = (std::max)(extra, min_grow - entries);
     CordRepRing* newrep = CordRepRing::New(entries, min_extra);
     newrep->Fill<false>(rep, rep->head(), rep->tail());
     CordRepRing::Delete(rep);
diff --git a/absl/strings/string_view.h b/absl/strings/string_view.h
index b276bdb..1f14a75 100644
--- a/absl/strings/string_view.h
+++ b/absl/strings/string_view.h
@@ -36,6 +36,7 @@
 #include <limits>
 #include <string>
 
+#include "absl/base/attributes.h"
 #include "absl/base/config.h"
 #include "absl/base/internal/throw_delegate.h"
 #include "absl/base/macros.h"
@@ -180,8 +181,8 @@
 
   template <typename Allocator>
   string_view(  // NOLINT(runtime/explicit)
-      const std::basic_string<char, std::char_traits<char>, Allocator>&
-          str) noexcept
+      const std::basic_string<char, std::char_traits<char>, Allocator>& str
+          ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept
       // This is implemented in terms of `string_view(p, n)` so `str.size()`
       // doesn't need to be reevaluated after `ptr_` is set.
       : string_view(str.data(), str.size()) {}
diff --git a/absl/time/internal/cctz/src/time_zone_fixed.cc b/absl/time/internal/cctz/src/time_zone_fixed.cc
index 303c024..f2b3294 100644
--- a/absl/time/internal/cctz/src/time_zone_fixed.cc
+++ b/absl/time/internal/cctz/src/time_zone_fixed.cc
@@ -53,7 +53,7 @@
 }  // namespace
 
 bool FixedOffsetFromName(const std::string& name, seconds* offset) {
-  if (name.compare(0, std::string::npos, "UTC", 3) == 0) {
+  if (name == "UTC" || name == "UTC0") {
     *offset = seconds::zero();
     return true;
   }
diff --git a/absl/time/internal/cctz/src/time_zone_lookup_test.cc b/absl/time/internal/cctz/src/time_zone_lookup_test.cc
index 9a1a8d6..6948c3e 100644
--- a/absl/time/internal/cctz/src/time_zone_lookup_test.cc
+++ b/absl/time/internal/cctz/src/time_zone_lookup_test.cc
@@ -717,6 +717,18 @@
 }
 #endif
 
+TEST(TimeZone, UTC) {
+  const time_zone utc = utc_time_zone();
+
+  time_zone loaded_utc;
+  EXPECT_TRUE(load_time_zone("UTC", &loaded_utc));
+  EXPECT_EQ(loaded_utc, utc);
+
+  time_zone loaded_utc0;
+  EXPECT_TRUE(load_time_zone("UTC0", &loaded_utc0));
+  EXPECT_EQ(loaded_utc0, utc);
+}
+
 TEST(TimeZone, NamedTimeZones) {
   const time_zone utc = utc_time_zone();
   EXPECT_EQ("UTC", utc.name());