diff --git a/libcxx/include/sstream b/libcxx/include/sstream --- a/libcxx/include/sstream +++ b/libcxx/include/sstream @@ -479,13 +479,7 @@ const_cast(__str_.data()) + __str_.size()); if (__mode_ & (ios_base::app | ios_base::ate)) { - while (__sz > INT_MAX) - { - this->pbump(INT_MAX); - __sz -= INT_MAX; - } - if (__sz > 0) - this->pbump(__sz); + this->__pbump(__sz); } } } @@ -619,7 +613,7 @@ if (__wch & ios_base::out) { this->setp(this->pbase(), this->epptr()); - this->pbump(__noff); + this->__pbump(__noff); } return pos_type(__noff); } diff --git a/libcxx/test/std/input.output/string.streams/stringstream.members/gcount.pass.cpp b/libcxx/test/std/input.output/string.streams/stringstream.members/gcount.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/input.output/string.streams/stringstream.members/gcount.pass.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// Test that tellp() does not break the stringstream after INT_MAX, due to use +// of pbump() that accept int. + +#include +#include +#include + +int main(int, char**) { +#if __SIZE_WIDTH__ == 64 + std::stringstream ss; + std::string payload(1 << 20, 'A'); + + for (size_t i = 0; i < (2ULL << 30) - payload.size(); i += payload.size()) { + assert(ss.tellp() != -1); + ss.write(payload.data(), payload.size()); + } + + assert(ss.tellp() != -1); + ss.write(payload.data(), payload.size()); + + assert(ss.tellp() != -1); + ss.write(payload.data(), payload.size()); +#endif + + return 0; +}