Fix raw_fd_ostream::write_impl hang with large output
authorJames Henderson <jh7370@my.bristol.ac.uk>
Thu, 26 Jul 2018 13:22:07 +0000 (13:22 +0000)
committerJames Henderson <jh7370@my.bristol.ac.uk>
Thu, 26 Jul 2018 13:22:07 +0000 (13:22 +0000)
On Windows when raw_fd_ostream::write_impl calls write, a 32 bit input
is required for character count. As a variable with size_t is used for
this argument on x64 integral demotion occurs. In the case of large
files an infinite loop follows.

See PR37926.

This fix allows the output of files larger than previous int32 limit.

Differential Revision: https://reviews.llvm.org/D48948

Patch by Owen Reynolds

Reviewed by: zturner

llvm-svn: 338027

llvm/lib/Support/raw_ostream.cpp

index e1e5fe7..b2260c1 100644 (file)
@@ -613,10 +613,10 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) {
   assert(FD >= 0 && "File already closed.");
   pos += Size;
 
-  // The maximum write size is limited to SSIZE_MAX because a write
-  // greater than SSIZE_MAX is implementation-defined in POSIX.
-  // Since SSIZE_MAX is not portable, we use SIZE_MAX >> 1 instead.
-  size_t MaxWriteSize = SIZE_MAX >> 1;
+  // The maximum write size is limited to INT32_MAX. A write
+  // greater than SSIZE_MAX is implementation-defined in POSIX,
+  // and Windows _write requires 32 bit input.
+  size_t MaxWriteSize = INT32_MAX;
 
 #if defined(__linux__)
   // It is observed that Linux returns EINVAL for a very large write (>2G).