diff --git a/libcxx/include/sstream b/libcxx/include/sstream --- a/libcxx/include/sstream +++ b/libcxx/include/sstream @@ -620,7 +620,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,41 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// All 32 bit arches that CI has: +// +// UNSUPPORTED: powerpc-ibm-aix +// UNSUPPORTED: armv7l-linux-gnueabihf +// UNSUPPORTED: armv8l-linux-gnueabihf +// UNSUPPORTED: i686-w64-windows-gnu + +// Test that tellp() does not break the stringstream after INT_MAX, due to use +// of pbump() that accept int. + +#include +#include +#include +#include + +int main(int, char**) { + std::stringstream ss; + std::string payload(INT_MAX - 1, '\0'); + + ss.write(payload.data(), payload.size()); + assert(ss.tellp() == INT_MAX - 1); + + ss.write("a", 1); + assert(ss.tellp() == INT_MAX); + + ss.write("b", 1); + assert(ss.tellp() == INT_MAX + 1ULL); + // it fails only after previous tellp() corrupts the internal field with int + // overflow + assert(ss.tellp() == INT_MAX + 1ULL); + + return 0; +}