Skip to content

Commit 594faba

Browse files
committed
[ClangImporter] Handle allowing PCM/PCH errors
Ignore errors when emitting/reading a PCM/PCH and Clang has `-fallow-(pcm|pch)-with-compiler-errors` set. Resolves rdar://85576570.
1 parent 7be6058 commit 594faba

File tree

3 files changed

+61
-5
lines changed

3 files changed

+61
-5
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -856,10 +856,12 @@ bool ClangImporter::canReadPCH(StringRef PCHFilename) {
856856
std::make_shared<clang::CompilerInvocation>(*Impl.Invocation);
857857
invocation->getPreprocessorOpts().DisablePCHOrModuleValidation =
858858
clang::DisableValidationForModuleKind::None;
859-
invocation->getPreprocessorOpts().AllowPCHWithCompilerErrors = false;
860859
invocation->getHeaderSearchOpts().ModulesValidateSystemHeaders = true;
861860
invocation->getLangOpts()->NeededByPCHOrCompilationUsesPCH = true;
862861
invocation->getLangOpts()->CacheGeneratedPCH = true;
862+
// If the underlying invocation is allowing PCH errors, then it "can be read",
863+
// even if it has its error bit set. Thus, don't override
864+
// `AllowPCHWithCompilerErrors`.
863865

864866
// ClangImporter::create adds a remapped MemoryBuffer that we don't need
865867
// here. Moreover, it's a raw pointer owned by the preprocessor options; if
@@ -1365,7 +1367,8 @@ bool ClangImporter::Implementation::importHeader(
13651367
// Don't even try to load the bridging header if the Clang AST is in a bad
13661368
// state. It could cause a crash.
13671369
auto &clangDiags = getClangASTContext().getDiagnostics();
1368-
if (clangDiags.hasUnrecoverableErrorOccurred())
1370+
if (clangDiags.hasUnrecoverableErrorOccurred() &&
1371+
!getClangInstance()->getPreprocessorOpts().AllowPCHWithCompilerErrors)
13691372
return true;
13701373

13711374
assert(adapter);
@@ -1465,7 +1468,8 @@ bool ClangImporter::Implementation::importHeader(
14651468
getBufferImporterForDiagnostics());
14661469

14671470
// FIXME: What do we do if there was already an error?
1468-
if (!hadError && clangDiags.hasErrorOccurred()) {
1471+
if (!hadError && clangDiags.hasErrorOccurred() &&
1472+
!getClangInstance()->getPreprocessorOpts().AllowPCHWithCompilerErrors) {
14691473
diagnose(diagLoc, diag::bridging_header_error, headerName);
14701474
return true;
14711475
}
@@ -1668,7 +1672,8 @@ ClangImporter::emitBridgingPCH(StringRef headerPath,
16681672
FrontendOpts, std::make_unique<clang::GeneratePCHAction>());
16691673
emitInstance->ExecuteAction(*action);
16701674

1671-
if (emitInstance->getDiagnostics().hasErrorOccurred()) {
1675+
if (emitInstance->getDiagnostics().hasErrorOccurred() &&
1676+
!emitInstance->getPreprocessorOpts().AllowPCHWithCompilerErrors) {
16721677
Impl.diagnose({}, diag::bridging_header_pch_error,
16731678
outputPCHPath, headerPath);
16741679
return true;
@@ -1728,7 +1733,8 @@ bool ClangImporter::emitPrecompiledModule(StringRef moduleMapPath,
17281733
std::make_unique<clang::GenerateModuleFromModuleMapAction>());
17291734
emitInstance->ExecuteAction(*action);
17301735

1731-
if (emitInstance->getDiagnostics().hasErrorOccurred()) {
1736+
if (emitInstance->getDiagnostics().hasErrorOccurred() &&
1737+
!FrontendOpts.AllowPCMWithCompilerErrors) {
17321738
Impl.diagnose({}, diag::emit_pcm_error, outputPath, moduleMapPath);
17331739
return true;
17341740
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// REQUIRES: objc_interop
2+
3+
// RUN: %empty-directory(%t)
4+
// RUN: mkdir -p %t/pch %t/pch-dir
5+
// RUN: split-file %s %t
6+
7+
// Check that the pch is output even though it has errors
8+
// RUN: %target-swift-frontend -emit-pch -o %t/pch/bridging-header.pch -Xcc -Xclang -Xcc -fallow-pcm-with-compiler-errors -Xcc -Xclang -Xcc -fmodule-format=raw %t/bridging-header.h
9+
// RUN: %target-swift-frontend -typecheck -verify -import-objc-header %t/pch/bridging-header.pch -Xcc -Xclang -Xcc -fallow-pcm-with-compiler-errors -Xcc -Xclang -Xcc -fmodule-format=raw %t/use.swift
10+
// RUN: ls %t/pch/*.pch | count 1
11+
12+
// Same but with implicit PCH instead
13+
// RUN: %target-swift-frontend -typecheck -verify -import-objc-header %t/bridging-header.h -pch-output-dir %t/pch-dir -Xcc -Xclang -Xcc -fallow-pcm-with-compiler-errors -Xcc -Xclang -Xcc -fmodule-format=raw %t/use.swift
14+
// RUN: ls %t/pch-dir/*.pch | count 1
15+
16+
// Second implicit run since we may go down a different path if the PCH already
17+
// exists
18+
// RUN: %target-swift-frontend -typecheck -verify -import-objc-header %t/bridging-header.h -pch-output-dir %t/pch-dir -Xcc -Xclang -Xcc -fallow-pcm-with-compiler-errors -Xcc -Xclang -Xcc -fmodule-format=raw %t/use.swift
19+
// RUN: ls %t/pch-dir/*.pch | count 1
20+
21+
//--- bridging-header.h
22+
@import DoesNotExist;
23+
24+
struct SomeTy {
25+
int a;
26+
};
27+
28+
//--- use.swift
29+
func use(s: SomeTy) {}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// RUN: %target-swift-emit-pcm -module-name m -o %t/m.pcm -Xcc -Xclang -Xcc -fallow-pcm-with-compiler-errors -Xcc -Xclang -Xcc -fmodule-format=raw %t/mods/module.map
5+
// RUN: %target-swift-frontend -typecheck -verify -Xcc -Xclang -Xcc -fallow-pcm-with-compiler-errors -Xcc -fmodule-file=%t/m.pcm %t/use.swift
6+
7+
//--- mods/module.map
8+
module m {
9+
header "m.h"
10+
}
11+
12+
//--- mods/m.h
13+
@import DoesNotExist;
14+
15+
struct SomeTy {
16+
int a;
17+
};
18+
19+
//--- use.swift
20+
import m
21+
func use(s: SomeTy) {}

0 commit comments

Comments
 (0)