Skip to content

Commit 7ad553f

Browse files
authored
Merge pull request #40273 from bnbarham/pch-allow-errors
[ClangImporter] Handle allowing PCM/PCH errors
2 parents adf712e + efcb5e3 commit 7ad553f

File tree

5 files changed

+72
-14
lines changed

5 files changed

+72
-14
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
}

lib/FrontendTool/FrontendTool.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1813,19 +1813,22 @@ createJSONFixItDiagnosticConsumerIfNeeded(
18131813

18141814
/// A PrettyStackTraceEntry to print frontend information useful for debugging.
18151815
class PrettyStackTraceFrontend : public llvm::PrettyStackTraceEntry {
1816-
const LangOptions &LangOpts;
1816+
const CompilerInvocation &Invocation;
18171817

18181818
public:
1819-
PrettyStackTraceFrontend(const LangOptions &langOpts)
1820-
: LangOpts(langOpts) {}
1819+
PrettyStackTraceFrontend(const CompilerInvocation &invocation)
1820+
: Invocation(invocation) {}
18211821

18221822
void print(llvm::raw_ostream &os) const override {
1823-
auto effective = LangOpts.EffectiveLanguageVersion;
1823+
auto effective = Invocation.getLangOptions().EffectiveLanguageVersion;
18241824
if (effective != version::Version::getCurrentLanguageVersion()) {
18251825
os << "Compiling with effective version " << effective;
18261826
} else {
18271827
os << "Compiling with the current language version";
18281828
}
1829+
if (Invocation.getFrontendOptions().AllowModuleWithCompilerErrors) {
1830+
os << " while allowing modules with compiler errors";
1831+
}
18291832
os << "\n";
18301833
};
18311834
};
@@ -1936,7 +1939,7 @@ int swift::performFrontend(ArrayRef<const char *> Args,
19361939
/// (leaks checking is not thread safe).
19371940
Invocation.getSILOptions().checkSILModuleLeaks = true;
19381941

1939-
PrettyStackTraceFrontend frontendTrace(Invocation.getLangOptions());
1942+
PrettyStackTraceFrontend frontendTrace(Invocation);
19401943

19411944
// Make an array of PrettyStackTrace objects to dump the configuration files
19421945
// we used to parse the arguments. These are RAII objects, so they and the
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) {}

test/Frontend/crash.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// RUN: not --crash %target-swift-frontend -typecheck -debug-crash-after-parse -filelist %t.filelist.txt 2>&1 | %FileCheck %s
33

44
// Check that we see the contents of the input file list in the crash log.
5-
// CHECK-NOT: Compiling with {{.*}} while allowing modules with compiler errors enabled
5+
// CHECK-NOT: while allowing modules with compiler errors
66
// CHECK-LABEL: Stack dump
77
// CHECK-NEXT: Program arguments: {{.*swift(-frontend)?(c?)(\.exe)?}}
88
// CHECK-NEXT: Swift version
@@ -14,12 +14,11 @@
1414

1515
// RUN: not --crash %target-swift-frontend -typecheck -debug-crash-after-parse -experimental-allow-module-with-compiler-errors %s 2>&1 | %FileCheck -check-prefix CHECK-ALLOW %s
1616
// CHECK-ALLOW: Program arguments: {{.*}} -experimental-allow-module-with-compiler-errors
17-
// CHECK-ALLOW: Compiling with effective version
17+
// CHECK-ALLOW: Compiling with effective version {{.*}} while allowing modules with compiler errors
1818

1919
// RUN: not --crash %target-swift-frontend -typecheck -debug-crash-after-parse -experimental-allow-module-with-compiler-errors -swift-version 5 %s 2>&1 | %FileCheck -check-prefix CHECK-CURRENT %s
2020
// CHECK-CURRENT: Program arguments: {{.*}} -experimental-allow-module-with-compiler-errors
21-
// CHECK-CURRENT: Compiling with the current language version
21+
// CHECK-CURRENT: Compiling with the current language version while allowing modules with compiler errors
2222

2323
func anchor() {}
2424
anchor()
25-

0 commit comments

Comments
 (0)