浏览代码

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.

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@324531 91177308-0d34-0410-b5e6-96231b3b80d8
Marshall Clow 7 年之前
父节点
当前提交
088e6015b2
共有 2 个文件被更改,包括 8 次插入5 次删除
  1. 7 3
      include/string
  2. 1 2
      test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp

+ 7 - 3
include/string

@@ -1363,9 +1363,13 @@ private:
     enum {__alignment = 16};
     enum {__alignment = 16};
     static _LIBCPP_INLINE_VISIBILITY
     static _LIBCPP_INLINE_VISIBILITY
     size_type __recommend(size_type __s) _NOEXCEPT
     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
     inline
     void __init(const value_type* __s, size_type __sz, size_type __reserve);
     void __init(const value_type* __s, size_type __sz, size_type __reserve);

+ 1 - 2
test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp

@@ -48,7 +48,7 @@ int main()
     test(S("12345678901234567890"), 'a', S("12345678901234567890a"));
     test(S("12345678901234567890"), 'a', S("12345678901234567890a"));
     }
     }
 #endif
 #endif
-#if 0
+
     {
     {
 // https://bugs.llvm.org/show_bug.cgi?id=31454
 // https://bugs.llvm.org/show_bug.cgi?id=31454
     std::basic_string<veryLarge> s;
     std::basic_string<veryLarge> s;
@@ -57,5 +57,4 @@ int main()
     s.push_back(vl);
     s.push_back(vl);
     s.push_back(vl);
     s.push_back(vl);
     }
     }
-#endif
 }
 }