Skip to content

Commit 5542bc3

Browse files
committed
[Serialization] Fix a bug in the serialization of resilient functions
The SIL serializer can decide not to serialize the body of functions in the SIL module, and only emit a declaration. If we keep the original linkage kind (public, private, etc) then the deserialized module won't pass verification because we do not allow internal functions to have external declarations. This commit changes the linkage kind for the functions that the serializer decides to emit as a declaration (without a body). rdar://21989088
1 parent 7c46d17 commit 5542bc3

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

include/swift/SIL/SILLinkage.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,19 @@ inline SILLinkage stripExternalFromLinkage(SILLinkage linkage) {
110110
return linkage;
111111
}
112112

113+
/// Add the 'external' attribute to \p linkage.
114+
inline SILLinkage addExternalToLinkage(SILLinkage linkage) {
115+
if (linkage == SILLinkage::Public)
116+
return SILLinkage::PublicExternal;
117+
if (linkage == SILLinkage::Hidden)
118+
return SILLinkage::HiddenExternal;
119+
if (linkage == SILLinkage::Shared)
120+
return SILLinkage::SharedExternal;
121+
if (linkage == SILLinkage::Private)
122+
return SILLinkage::PrivateExternal;
123+
return linkage;
124+
}
125+
113126
/// Return whether the linkage indicates that an object has a
114127
/// definition outside the current SILModule.
115128
inline bool isAvailableExternally(SILLinkage linkage) {

lib/Serialization/SerializeSIL.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,14 +255,24 @@ void SILSerializer::writeSILFunction(const SILFunction &F, bool DeclOnly) {
255255
if (hasSharedVisibility(Linkage))
256256
Linkage = SILLinkage::Shared;
257257

258+
// Check if we need to emit a body for this function.
259+
bool NoBody = DeclOnly || isAvailableExternally(Linkage) ||
260+
F.isExternalDeclaration();
261+
262+
// If we don't emit a function body then make sure to mark the decleration
263+
// as available externally.
264+
if (NoBody) {
265+
Linkage = addExternalToLinkage(Linkage);
266+
}
267+
258268
SILFunctionLayout::emitRecord(
259269
Out, ScratchRecord, abbrCode, toStableSILLinkage(Linkage),
260270
(unsigned)F.isTransparent(), (unsigned)F.isFragile(),
261271
(unsigned)F.isThunk(), (unsigned)F.isGlobalInit(),
262272
(unsigned)F.getInlineStrategy(), (unsigned)F.getEffectsKind(),
263273
FnID, SemanticsID);
264274

265-
if (DeclOnly || isAvailableExternally(Linkage) || F.isExternalDeclaration())
275+
if (NoBody)
266276
return;
267277

268278
// Write the body's context archetypes, unless we don't actually have a body.

0 commit comments

Comments
 (0)