diff --git a/lib/Driver/Compilation.cpp b/lib/Driver/Compilation.cpp index ff8d2cc579d19..8ec28ae116477 100644 --- a/lib/Driver/Compilation.cpp +++ b/lib/Driver/Compilation.cpp @@ -49,6 +49,10 @@ #include #include +#if defined(_WIN32) +#include +#include +#endif #define DEBUG_TYPE "batch-mode" @@ -727,6 +731,23 @@ namespace driver { : TaskFinishedResponse::StopExecution; } +#if defined(_WIN32) + struct FileBinaryModeRAII { + FileBinaryModeRAII(FILE *F) : F(F) { + PrevMode = _setmode(_fileno(F), _O_BINARY); + } + ~FileBinaryModeRAII() { + _setmode(_fileno(F), PrevMode); + } + FILE *F; + int PrevMode; + }; +#else + struct FileBinaryModeRAII { + FileBinaryModeRAII(FILE *) {} + }; +#endif + void processOutputOfFinishedProcess(ProcessId Pid, int ReturnCode, const Job *const FinishedCmd, StringRef Output, @@ -739,8 +760,14 @@ namespace driver { case OutputLevel::Verbose: // Send the buffered output to stderr, though only if we // support getting buffered output. - if (TaskQueue::supportsBufferingOutput()) + if (TaskQueue::supportsBufferingOutput()) { + // Temporarily change stderr to binary mode to avoid double + // LF -> CR LF conversions on the outputs from child + // processes, which have already this conversion appplied. + // This makes a difference only for Windows. + FileBinaryModeRAII F(stderr); llvm::errs() << Output; + } break; case OutputLevel::Parseable: emitParseableOutputForEachFinishedJob(Pid, ReturnCode, Output, diff --git a/test/diagnostics/Inputs/extra-newlines-2.swift b/test/diagnostics/Inputs/extra-newlines-2.swift new file mode 100644 index 0000000000000..f51d437ff5ec4 --- /dev/null +++ b/test/diagnostics/Inputs/extra-newlines-2.swift @@ -0,0 +1,2 @@ +// Intentionally blank. + diff --git a/test/diagnostics/extra-newlines.swift b/test/diagnostics/extra-newlines.swift new file mode 100644 index 0000000000000..5f65f7dc48c51 --- /dev/null +++ b/test/diagnostics/extra-newlines.swift @@ -0,0 +1,22 @@ +// Check that there are no extra newlines in the driver diagnostics output due to +// double LF -> CR LF conversions on child processes output on Windows. +// +// Compile more than one source files to trigger the use of the driver +// task queue and child processes. + +// RUN: %line-directive %s %S/Inputs/extra-newlines-2.swift -- %swiftc_driver -c -diagnostic-style=swift -no-color-diagnostics %s %S/Inputs/extra-newlines-2.swift -module-name Foo 2>&1 | %FileCheck %s + +// UNSUPPORTED: swift_swift_parser + +// Check that there are no extra newlines between diagnostics lines + +// CHECK: {{[=]+}} SOURCE_DIR{{[/\]+}}test{{[/\]+}}diagnostics{{[/\]+}}extra-newlines.swift:[[#LINE:]]:5 +// CHECK-NEXT: [[#LINE-1]] | func foo(a: Int, b: Int) { +// CHECK-NEXT: [[#LINE]] | a + b +// CHECK-NEXT: | ~ ~ +// CHECK-NEXT: | ^ warning: result of operator '+' is unused +// CHECK-NEXT: [[#LINE+1]] | } + +func foo(a: Int, b: Int) { + a + b +} \ No newline at end of file