Fix PR#31454 - 'basic_string<T>::push_back() crashes if sizeof(T)>sizeof(long long)'. We were mishandling the small-string optimization calculations for very large 'characters'. This may be an ABI change (change the size of) strings of very large 'characters', but since they never worked, I'm not too concerned.

llvm-svn: 324531
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: fc940277cba00b3a023c8c0f15360df73319c2a4
diff --git a/include/string b/include/string
index b213cd4..f89ef57 100644
--- a/include/string
+++ b/include/string
@@ -1363,9 +1363,13 @@
     enum {__alignment = 16};
     static _LIBCPP_INLINE_VISIBILITY
     size_type __recommend(size_type __s) _NOEXCEPT
-        {return (__s < __min_cap ? static_cast<size_type>(__min_cap) :
-                 __align_it<sizeof(value_type) < __alignment ?
-                            __alignment/sizeof(value_type) : 1 > (__s+1)) - 1;}
+        {
+        if (__s < __min_cap) return static_cast<size_type>(__min_cap) - 1;
+        size_type __guess = __align_it<sizeof(value_type) < __alignment ?
+                     __alignment/sizeof(value_type) : 1 > (__s+1) - 1;
+        if (__guess == __min_cap) ++__guess;
+        return __guess;
+        }
 
     inline
     void __init(const value_type* __s, size_type __sz, size_type __reserve);
diff --git a/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp b/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp
index 5ca5aaf..1284465 100644
--- a/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp
+++ b/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp
@@ -48,7 +48,7 @@
     test(S("12345678901234567890"), 'a', S("12345678901234567890a"));
     }
 #endif
-#if 0
+
     {
 // https://bugs.llvm.org/show_bug.cgi?id=31454
     std::basic_string<veryLarge> s;
@@ -57,5 +57,4 @@
     s.push_back(vl);
     s.push_back(vl);
     }
-#endif
 }