Skip to content

Commit 2301bff

Browse files
authored
Add some defensive checks against invalid serialization (#22466)
If a non-serializable Decl or Type makes it into serialization logic in a release build, an invalid swiftmodule might be produced silently, leading to crashes in clients. Try to catch this with an on-in-Release check that /something/ was serialized. (This is my best guess at how rdar://problem/47459323 occurred.)
1 parent 60da82b commit 2301bff

File tree

1 file changed

+19
-1
lines changed

1 file changed

+19
-1
lines changed

lib/Serialization/Serialization.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2666,7 +2666,16 @@ void Serializer::writeDecl(const Decl *D) {
26662666
(void)id;
26672667

26682668
assert((id - 1) == DeclOffsets.size());
2669+
assert((TypeOffsets.empty() || TypeOffsets.back() != Out.GetCurrentBitNo()) &&
2670+
"encoding Decl and Type to the same offset");
26692671
DeclOffsets.push_back(Out.GetCurrentBitNo());
2672+
SWIFT_DEFER {
2673+
// This is important enough to leave on in Release builds.
2674+
if (DeclOffsets.back() == Out.GetCurrentBitNo()) {
2675+
llvm::PrettyStackTraceString message("failed to serialize anything");
2676+
abort();
2677+
}
2678+
};
26702679

26712680
assert(!D->isInvalid() && "cannot create a module with an invalid decl");
26722681
if (isDeclXRef(D)) {
@@ -3677,14 +3686,23 @@ static TypeAliasDecl *findTypeAliasForBuiltin(ASTContext &Ctx, Type T) {
36773686

36783687
void Serializer::writeType(Type ty) {
36793688
using namespace decls_block;
3689+
PrettyStackTraceType traceRAII(ty->getASTContext(), "serializing", ty);
36803690

36813691
auto id = DeclAndTypeIDs[ty];
36823692
assert(id != 0 && "type not referenced properly");
36833693
(void)id;
36843694

36853695
assert((id - 1) == TypeOffsets.size());
3686-
3696+
assert((DeclOffsets.empty() || DeclOffsets.back() != Out.GetCurrentBitNo()) &&
3697+
"encoding Decl and Type to the same offset");
36873698
TypeOffsets.push_back(Out.GetCurrentBitNo());
3699+
SWIFT_DEFER {
3700+
// This is important enough to leave on in Release builds.
3701+
if (TypeOffsets.back() == Out.GetCurrentBitNo()) {
3702+
llvm::PrettyStackTraceString message("failed to serialize anything");
3703+
abort();
3704+
}
3705+
};
36883706

36893707
switch (ty->getKind()) {
36903708
case TypeKind::Error:

0 commit comments

Comments
 (0)