diff --git a/lld/test/ELF/lto/emit-llvm.ll b/lld/test/ELF/lto/emit-llvm.ll --- a/lld/test/ELF/lto/emit-llvm.ll +++ b/lld/test/ELF/lto/emit-llvm.ll @@ -4,6 +4,10 @@ ; RUN: ld.lld --plugin-opt=emit-llvm -o %t.out.o %t.o ; RUN: llvm-dis < %t.out.o -o - | FileCheck %s +;; Regression test for D112297: bitcode writer used to crash when +;; --plugin-opt=emit-llvmis enabled and the output is /dev/null. +; RUN: ld.lld --plugin-opt=emit-llvm -mllvm -bitcode-flush-threshold=0 -o /dev/null %t.o + ; CHECK: define internal void @main() target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h --- a/llvm/include/llvm/Support/raw_ostream.h +++ b/llvm/include/llvm/Support/raw_ostream.h @@ -444,6 +444,7 @@ int FD; bool ShouldClose; bool SupportsSeeking = false; + bool IsRegularFile = false; mutable Optional HasColors; #ifdef _WIN32 @@ -514,6 +515,8 @@ bool supportsSeeking() const { return SupportsSeeking; } + bool isRegularFile() const { return IsRegularFile; } + /// Flushes the stream and repositions the underlying file descriptor position /// to the offset specified from the beginning of the file. uint64_t seek(uint64_t off); diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp --- a/llvm/lib/Support/raw_ostream.cpp +++ b/llvm/lib/Support/raw_ostream.cpp @@ -643,13 +643,14 @@ // Get the starting position. off_t loc = ::lseek(FD, 0, SEEK_CUR); -#ifdef _WIN32 - // MSVCRT's _lseek(SEEK_CUR) doesn't return -1 for pipes. sys::fs::file_status Status; std::error_code EC = status(FD, Status); - SupportsSeeking = !EC && Status.type() == sys::fs::file_type::regular_file; + IsRegularFile = Status.type() == sys::fs::file_type::regular_file; +#ifdef _WIN32 + // MSVCRT's _lseek(SEEK_CUR) doesn't return -1 for pipes. + SupportsSeeking = !EC && IsRegularFile; #else - SupportsSeeking = loc != (off_t)-1; + SupportsSeeking = !EC && loc != (off_t)-1; #endif if (!SupportsSeeking) pos = 0; @@ -914,8 +915,7 @@ if (EC) return; - // Do not support non-seekable files. - if (!supportsSeeking()) + if (!isRegularFile()) EC = std::make_error_code(std::errc::invalid_argument); }