Skip to content

Commit a3e4f1a

Browse files
authored
Merge pull request #37472 from bnbarham/cleanup-allow-errors
[Serialization] Add whether allowing errors to the pretty stack output
2 parents 4e2a502 + cbbc29b commit a3e4f1a

File tree

13 files changed

+112
-36
lines changed

13 files changed

+112
-36
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -793,8 +793,9 @@ ERROR(serialization_fatal,Fatal,
793793
SWIFT_BUG_REPORT_MESSAGE,
794794
(StringRef))
795795
NOTE(serialization_misc_version,none,
796-
"module '%0' full misc version is '%1'",
797-
(StringRef, StringRef))
796+
"module '%0' full misc version is '%1'"
797+
"%select{ (built while allowing compiler errors)|}2",
798+
(StringRef, StringRef, bool))
798799
NOTE(serialization_compatibility_version_mismatch,none,
799800
"compiling as Swift %0, with '%1' built as Swift %2 "
800801
"(this is supported but may expose additional compiler issues)",

lib/FrontendTool/FrontendTool.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2046,6 +2046,11 @@ int swift::performFrontend(ArrayRef<const char *> Args,
20462046
return finishDiagProcessing(1, /*verifierEnabled*/ false);
20472047
}
20482048

2049+
Optional<llvm::PrettyStackTraceString> allowErrorsStackTrace;
2050+
if (Invocation.getFrontendOptions().AllowModuleWithCompilerErrors)
2051+
allowErrorsStackTrace.emplace("While allowing modules with compiler errors "
2052+
"enabled");
2053+
20492054
// Make an array of PrettyStackTrace objects to dump the configuration files
20502055
// we used to parse the arguments. These are RAII objects, so they and the
20512056
// buffers they refer to must be kept alive in order to be useful. (That is,

lib/Serialization/Deserialization.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,9 @@ static void skipRecord(llvm::BitstreamCursor &cursor, unsigned recordKind) {
169169
void ModuleFile::fatal(llvm::Error error) {
170170
if (FileContext) {
171171
getContext().Diags.diagnose(SourceLoc(), diag::serialization_fatal, Core->Name);
172-
getContext().Diags.diagnose(SourceLoc(), diag::serialization_misc_version,
173-
Core->Name, Core->MiscVersion);
172+
getContext().Diags.diagnose(
173+
SourceLoc(), diag::serialization_misc_version, Core->Name,
174+
Core->MiscVersion, allowCompilerErrors());
174175

175176
if (!Core->CompatibilityVersion.empty()) {
176177
if (getContext().LangOpts.EffectiveLanguageVersion
@@ -2512,7 +2513,7 @@ class DeclDeserializer {
25122513
name = VD->getName();
25132514
}
25142515

2515-
auto diagId = ctx.LangOpts.AllowModuleWithCompilerErrors
2516+
auto diagId = MF.allowCompilerErrors()
25162517
? diag::serialization_allowing_invalid_decl
25172518
: diag::serialization_invalid_decl;
25182519
ctx.Diags.diagnose(SourceLoc(), diagId, name,
@@ -3092,7 +3093,7 @@ class DeclDeserializer {
30923093
declOrOffset = param;
30933094

30943095
auto paramTy = MF.getType(interfaceTypeID);
3095-
if (paramTy->hasError() && !MF.isAllowModuleWithCompilerErrorsEnabled()) {
3096+
if (paramTy->hasError() && !MF.allowCompilerErrors()) {
30963097
// FIXME: This should never happen, because we don't serialize
30973098
// error types.
30983099
DC->printContext(llvm::errs());
@@ -5872,7 +5873,7 @@ class TypeDeserializer {
58725873
return origTyOrError.takeError();
58735874

58745875
auto origTy = *origTyOrError;
5875-
auto diagId = ctx.LangOpts.AllowModuleWithCompilerErrors
5876+
auto diagId = MF.allowCompilerErrors()
58765877
? diag::serialization_allowing_error_type
58775878
: diag::serialization_error_type;
58785879
// Generally not a super useful diagnostic, so only output once if there
@@ -5910,8 +5911,7 @@ Expected<Type> ModuleFile::getTypeChecked(TypeID TID) {
59105911

59115912
#ifndef NDEBUG
59125913
PrettyStackTraceType trace(getContext(), "deserializing", typeOrOffset.get());
5913-
if (typeOrOffset.get()->hasError() &&
5914-
!isAllowModuleWithCompilerErrorsEnabled()) {
5914+
if (typeOrOffset.get()->hasError() && !allowCompilerErrors()) {
59155915
typeOrOffset.get()->dump(llvm::errs());
59165916
llvm_unreachable("deserialization produced an invalid type "
59175917
"(rdar://problem/30382791)");
@@ -6372,7 +6372,7 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance,
63726372
auto isConformanceReq = [](const Requirement &req) {
63736373
return req.getKind() == RequirementKind::Conformance;
63746374
};
6375-
if (!isAllowModuleWithCompilerErrorsEnabled() &&
6375+
if (!allowCompilerErrors() &&
63766376
conformanceCount != llvm::count_if(proto->getRequirementSignature(),
63776377
isConformanceReq)) {
63786378
fatal(llvm::make_error<llvm::StringError>(
@@ -6715,3 +6715,9 @@ Optional<ForeignAsyncConvention> ModuleFile::maybeReadForeignAsyncConvention() {
67156715
completionHandlerErrorFlagParamIndex,
67166716
errorFlagPolarity);
67176717
}
6718+
6719+
void serialization::PrettyStackTraceModuleFile::outputModuleBuildInfo(
6720+
raw_ostream &os) const {
6721+
if (MF.compiledAllowingCompilerErrors())
6722+
os << " (built while allowing compiler errors)";
6723+
}

lib/Serialization/DeserializationErrors.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,8 +470,12 @@ class PrettyStackTraceModuleFile : public llvm::PrettyStackTraceEntry {
470470
: PrettyStackTraceModuleFile("While reading from", module) {}
471471

472472
void print(raw_ostream &os) const override {
473-
os << Action << " \'" << getNameOfModule(&MF) << "'\n";
473+
os << Action << " \'" << getNameOfModule(&MF) << "'";
474+
outputModuleBuildInfo(os);
475+
os << "\n";
474476
}
477+
478+
void outputModuleBuildInfo(raw_ostream &os) const;
475479
};
476480

477481
class PrettyStackTraceModuleFileCore : public llvm::PrettyStackTraceEntry {

lib/Serialization/ModuleFile.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ ModuleFile::ModuleFile(std::shared_ptr<const ModuleFileSharedCore> core)
117117
allocateBuffer(Identifiers, core->Identifiers);
118118
}
119119

120+
bool ModuleFile::allowCompilerErrors() const {
121+
return getContext().LangOpts.AllowModuleWithCompilerErrors;
122+
}
123+
120124
Status ModuleFile::associateWithFileContext(FileUnit *file, SourceLoc diagLoc,
121125
bool recoverFromIncompatibility) {
122126
PrettyStackTraceModuleFile stackEntry(*this);

lib/Serialization/ModuleFile.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -478,10 +478,14 @@ class ModuleFile
478478

479479
/// Whether this module is compiled while allowing errors
480480
/// ('-experimental-allow-module-with-compiler-errors').
481-
bool isAllowModuleWithCompilerErrorsEnabled() const {
481+
bool compiledAllowingCompilerErrors() const {
482482
return Core->Bits.IsAllowModuleWithCompilerErrorsEnabled;
483483
}
484484

485+
/// Whether currently allowing modules with compiler errors (ie.
486+
/// '-experimental-allow-module-with-compiler-errors' is currently enabled).
487+
bool allowCompilerErrors() const;
488+
485489
/// \c true if this module has incremental dependency information.
486490
bool hasIncrementalInfo() const { return Core->hasIncrementalInfo(); }
487491

lib/Serialization/Serialization.cpp

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,7 @@ using namespace llvm::support;
7676
using swift::version::Version;
7777
using llvm::BCBlockRAII;
7878

79-
80-
ASTContext &SerializerBase::getASTContext() {
81-
return M->getASTContext();
82-
}
79+
ASTContext &SerializerBase::getASTContext() const { return M->getASTContext(); }
8380

8481
/// Used for static_assert.
8582
static constexpr bool declIDFitsIn32Bits() {
@@ -644,8 +641,9 @@ serialization::TypeID Serializer::addTypeRef(Type ty) {
644641

645642
#ifndef NDEBUG
646643
PrettyStackTraceType trace(M->getASTContext(), "serializing", typeToSerialize);
647-
assert(M->getASTContext().LangOpts.AllowModuleWithCompilerErrors ||
648-
!typeToSerialize || !typeToSerialize->hasError() && "serializing type with an error");
644+
assert((allowCompilerErrors() || !typeToSerialize ||
645+
!typeToSerialize->hasError()) &&
646+
"serializing type with an error");
649647
#endif
650648

651649
return TypesToSerialize.addRef(typeToSerialize);
@@ -1015,7 +1013,7 @@ void Serializer::writeHeader(const SerializationOptions &options) {
10151013
Strategy.emit(ScratchRecord, unsigned(M->getResilienceStrategy()));
10161014
}
10171015

1018-
if (getASTContext().LangOpts.AllowModuleWithCompilerErrors) {
1016+
if (allowCompilerErrors()) {
10191017
options_block::IsAllowModuleWithCompilerErrorsEnabledLayout
10201018
AllowErrors(Out);
10211019
AllowErrors.emit(ScratchRecord);
@@ -1439,8 +1437,7 @@ void Serializer::writeASTBlockEntity(
14391437
using namespace decls_block;
14401438

14411439
// The conformance must be complete, or we can't serialize it.
1442-
assert(conformance->isComplete() ||
1443-
getASTContext().LangOpts.AllowModuleWithCompilerErrors);
1440+
assert(conformance->isComplete() || allowCompilerErrors());
14441441
assert(NormalConformancesToSerialize.hasRef(conformance));
14451442

14461443
auto protocol = conformance->getProtocol();
@@ -2861,7 +2858,7 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
28612858
// Retrieve the type of the pattern.
28622859
auto getPatternType = [&] {
28632860
if (!pattern->hasType()) {
2864-
if (S.getASTContext().LangOpts.AllowModuleWithCompilerErrors)
2861+
if (S.allowCompilerErrors())
28652862
return ErrorType::get(S.getASTContext());
28662863
llvm_unreachable("all nodes should have types");
28672864
}
@@ -3625,8 +3622,7 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
36253622
getRawStableDefaultArgumentKind(argKind),
36263623
defaultArgumentText);
36273624

3628-
if (interfaceType->hasError() &&
3629-
!S.getASTContext().LangOpts.AllowModuleWithCompilerErrors) {
3625+
if (interfaceType->hasError() && !S.allowCompilerErrors()) {
36303626
param->getDeclContext()->printContext(llvm::errs());
36313627
interfaceType->dump(llvm::errs());
36323628
llvm_unreachable("error in interface type of parameter");
@@ -3993,8 +3989,8 @@ void Serializer::writeASTBlockEntity(const Decl *D) {
39933989
}
39943990
};
39953991

3996-
assert(getASTContext().LangOpts.AllowModuleWithCompilerErrors ||
3997-
!D->isInvalid() && "cannot create a module with an invalid decl");
3992+
assert((allowCompilerErrors() || !D->isInvalid()) &&
3993+
"cannot create a module with an invalid decl");
39983994
if (isDeclXRef(D)) {
39993995
writeCrossReference(D);
40003996
return;
@@ -4156,7 +4152,7 @@ class Serializer::TypeSerializer : public TypeVisitor<TypeSerializer> {
41564152
void visitType(const TypeBase *) = delete;
41574153

41584154
void visitErrorType(const ErrorType *ty) {
4159-
if (S.getASTContext().LangOpts.AllowModuleWithCompilerErrors) {
4155+
if (S.allowCompilerErrors()) {
41604156
using namespace decls_block;
41614157
unsigned abbrCode = S.DeclTypeAbbrCodes[ErrorTypeLayout::Code];
41624158
ErrorTypeLayout::emitRecord(S.Out, S.ScratchRecord, abbrCode,
@@ -5252,8 +5248,7 @@ static void collectInterestingNestedDeclarations(
52525248
if (!nominalParent) {
52535249
const DeclContext *DC = member->getDeclContext();
52545250
nominalParent = DC->getSelfNominalTypeDecl();
5255-
assert(nominalParent ||
5256-
nestedType->getASTContext().LangOpts.AllowModuleWithCompilerErrors &&
5251+
assert((nominalParent || S.allowCompilerErrors()) &&
52575252
"parent context is not a type or extension");
52585253
}
52595254
nestedTypeDecls[nestedType->getName()].push_back({
@@ -5539,6 +5534,10 @@ void Serializer::writeToStream(
55395534
S.writeToStream(os);
55405535
}
55415536

5537+
bool Serializer::allowCompilerErrors() const {
5538+
return getASTContext().LangOpts.AllowModuleWithCompilerErrors;
5539+
}
5540+
55425541
void swift::serializeToBuffers(
55435542
ModuleOrSourceFile DC, const SerializationOptions &options,
55445543
std::unique_ptr<llvm::MemoryBuffer> *moduleBuffer,

lib/Serialization/Serialization.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class SerializerBase {
7272
public:
7373
SerializerBase(ArrayRef<unsigned char> signature, ModuleOrSourceFile DC);
7474

75-
ASTContext &getASTContext();
75+
ASTContext &getASTContext() const;
7676
};
7777

7878
class Serializer : public SerializerBase {
@@ -538,6 +538,8 @@ class Serializer : public SerializerBase {
538538
/// Writes a set of generic requirements.
539539
void writeGenericRequirements(ArrayRef<Requirement> requirements,
540540
const std::array<unsigned, 256> &abbrCodes);
541+
542+
bool allowCompilerErrors() const;
541543
};
542544

543545
/// Serialize module documentation to the given stream.

test/Frontend/crash.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010
// CHECK-NEXT: test{{[\\/]}}Frontend{{[\\/]}}crash.swift{{$}}
1111
// CHECK-NEXT: ---
1212

13+
// Check that a message when allowing errors is output
14+
// 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
15+
// CHECK-ALLOW-LABEL: Stack dump
16+
// CHECK-ALLOW: While allowing modules with compiler errors enabled
17+
1318
func anchor() {}
1419
anchor()
1520

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: touch %t/empty.swift
3+
4+
// RUN: %target-swift-frontend -emit-module -o %t/errors.partial.swiftmodule -module-name errors -experimental-allow-module-with-compiler-errors %s
5+
// RUN: %target-swift-frontend -emit-module -o %t/errorsempty.partial.swiftmodule -module-name errors %t/empty.swift
6+
7+
// Note - running the merge without allow errors to force a crash, we want
8+
// to check if there's a message about allowing compiler errors for the
9+
// deserialized module
10+
// RUN: not --crash %target-swift-frontend -module-name errors -emit-module -o %t/errors.swiftmodule %t/errors.partial.swiftmodule %t/errorsempty.partial.swiftmodule 2>&1 | %FileCheck %s
11+
12+
// REQUIRES: asserts
13+
14+
typealias AnAlias = SomeStruct
15+
16+
// CHECK: While reading from 'errors' (built while allowing compiler errors)

0 commit comments

Comments
 (0)