Skip to content

Commit 689663d

Browse files
committed
[BatchMode] Fix interaction of bridging PCH and file specific diag consumer.
In batch mode, when using serialized diagnostics, we have a FileSpecificDiagnosticConsumer splitting diags out to separate .dia files (one per primary). This constructs a mapping from filenames to consumers when it's first given a diag. So far so good. It assumes, however, that there are source buffers to be found for each input file it knows the name of. This is true -- and useful to assert -- once the source buffers are set up. It's also a prerequisite for building the map it uses to direct diags. Unfortunately there's a small window between the consumer being built and the source manager getting buffers, and in this window we attach to a bridging PCH. If that attaching generates a diag of itself (say due to a bogus module map or such) then the diag consumer is asked to build its map without source buffers. The thing to do here is just to fall back to the "no mapping found" case; the only tricky part is identifying when we're in that window of time. I've chosen to use the approximating condition of "none of the file buffers exist at all".
1 parent a61cd12 commit 689663d

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

lib/AST/DiagnosticConsumer.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "swift/AST/DiagnosticEngine.h"
2020
#include "swift/Basic/Defer.h"
2121
#include "swift/Basic/SourceManager.h"
22+
#include "llvm/ADT/STLExtras.h"
2223
#include "llvm/ADT/StringRef.h"
2324
#include "llvm/ADT/StringSet.h"
2425
#include "llvm/Support/Debug.h"
@@ -116,6 +117,20 @@ FileSpecificDiagnosticConsumer::consumerForLocation(SourceManager &SM,
116117
// FileSpecificDiagnosticConsumer to be set up before the source files are
117118
// actually loaded.
118119
if (ConsumersOrderedByRange.empty()) {
120+
121+
// It's possible to get here while a bridging header PCH is being
122+
// attached-to, if there's some sort of AST-reader warning or error, which
123+
// happens before CompilerInstance::setUpInputs(), at which point _no_
124+
// source buffers are loaded in yet. In that case we return nullptr, rather
125+
// than trying to build a nonsensical map (and actually crashing since we
126+
// can't find buffers for the inputs).
127+
assert(!SubConsumers.empty());
128+
if (!SM.getIDForBufferIdentifier(SubConsumers.begin()->first).hasValue()) {
129+
assert(llvm::none_of(SubConsumers, [&](const ConsumerPair &pair) {
130+
return SM.getIDForBufferIdentifier(pair.first).hasValue();
131+
}));
132+
return nullptr;
133+
}
119134
auto *mutableThis = const_cast<FileSpecificDiagnosticConsumer*>(this);
120135
mutableThis->computeConsumersOrderedByRange(SM);
121136
}

test/Driver/batch_mode_bridging_pch.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,18 @@
55
//
66
// RUN: %swiftc_driver -enable-bridging-pch -v -import-objc-header %t/foo-bridging-header.h -enable-batch-mode -c -emit-module -module-name main -j 2 %t/file-01.swift %t/file-02.swift %t/file-03.swift %t/main.swift %s 2>&1 | %FileCheck %s
77
//
8+
// Next we make a module map with an unknown attribute, which will cause an
9+
// AST-reader warning while (re)parsing the module map, while attaching a PCH.
10+
// We turn on serialized diagnostics in the frontends, and check that that
11+
// warning, issued before the batch-mode multi-file diagnostic multiplexor has
12+
// its file mappings established, does not crash the multiplexor.
13+
//
14+
// RUN: %empty-directory(%t/MyModule)
15+
// RUN: echo 'module MyModule [DefinitelyNotAnAttribute] { header "header.h" export * }' >%t/MyModule/module.modulemap
16+
// RUN: touch %t/MyModule/header.h
17+
// RUN: echo '#include "MyModule/header.h"' >>%t/foo-bridging-header.h
18+
// RUN: %swiftc_driver -enable-bridging-pch -v -I %t -import-objc-header %t/foo-bridging-header.h -enable-batch-mode -c -emit-module -module-name main -j 2 %t/file-01.swift %t/file-02.swift %t/file-03.swift %t/main.swift -serialize-diagnostics %s 2>&1 | %FileCheck %s
19+
//
820
// CHECK: -emit-pch
921
// CHECK: -primary-file {{.*}}/file-01.swift -primary-file {{.*}}/file-02.swift
1022

0 commit comments

Comments
 (0)