Skip to content

Commit 5bd077a

Browse files
committed
[SIL] Keep alive @_alwaysEmitIntoClient decls with opaque result types
If such declarations have availability conditions they have to be kept alive until IRGen to emit opaque type descriptor that is going be used at runtime to determine the underlying type. This is important for "optimized" mode only because in non-optimized mode "shared" symbol survives SILGen.
1 parent dceed56 commit 5bd077a

File tree

3 files changed

+37
-7
lines changed

3 files changed

+37
-7
lines changed

include/swift/SIL/SILFunction.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,6 +1121,32 @@ class SILFunction
11211121
return false;
11221122
}
11231123

1124+
/// Returns true if this function belongs to a declaration that
1125+
/// has `@_alwaysEmitIntoClient` attribute.
1126+
bool markedAsAlwaysEmitIntoClient() const {
1127+
if (!hasLocation())
1128+
return false;
1129+
1130+
auto *V = getLocation().getAsASTNode<ValueDecl>();
1131+
return V && V->getAttrs().hasAttribute<AlwaysEmitIntoClientAttr>();
1132+
}
1133+
1134+
/// Returns true if this function belongs to a declaration that returns
1135+
/// an opaque result type with one or more availability conditions that are
1136+
/// allowed to produce a different underlying type at runtime.
1137+
bool hasOpaqueResultTypeWithAvailabilityConditions() const {
1138+
if (!hasLocation())
1139+
return false;
1140+
1141+
if (auto *V = getLocation().getAsASTNode<ValueDecl>()) {
1142+
auto *opaqueResult = V->getOpaqueResultTypeDecl();
1143+
return opaqueResult &&
1144+
opaqueResult->hasConditionallyAvailableSubstitutions();
1145+
}
1146+
1147+
return false;
1148+
}
1149+
11241150
//===--------------------------------------------------------------------===//
11251151
// Block List Access
11261152
//===--------------------------------------------------------------------===//

lib/IRGen/IRGenSIL.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2232,18 +2232,15 @@ void IRGenSILFunction::emitSILFunction() {
22322232
IGM.IRGen.addDynamicReplacement(CurSILFn);
22332233

22342234
if (CurSILFn->getLinkage() == SILLinkage::Shared) {
2235-
if (auto *V = CurSILFn->getLocation().getAsASTNode<ValueDecl>()) {
2236-
bool alwaysEmitIntoClient =
2237-
V->getAttrs().hasAttribute<AlwaysEmitIntoClientAttr>();
2235+
if (CurSILFn->markedAsAlwaysEmitIntoClient() &&
2236+
CurSILFn->hasOpaqueResultTypeWithAvailabilityConditions()) {
2237+
auto *V = CurSILFn->getLocation().castToASTNode<ValueDecl>();
22382238
auto *opaqueResult = V->getOpaqueResultTypeDecl();
22392239
// `@_alwaysEmitIntoClient` declaration with opaque result
22402240
// has to emit opaque type descriptor into client module
22412241
// when it has availability conditions because the underlying
22422242
// type in such cases is unknown until runtime.
2243-
if (alwaysEmitIntoClient && opaqueResult &&
2244-
opaqueResult->hasConditionallyAvailableSubstitutions()) {
2245-
IGM.maybeEmitOpaqueTypeDecl(opaqueResult);
2246-
}
2243+
IGM.maybeEmitOpaqueTypeDecl(opaqueResult);
22472244
}
22482245
}
22492246

lib/SIL/IR/SILFunction.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,13 @@ SILFunction::isPossiblyUsedExternally() const {
708708
if (isDistributed() && isThunk())
709709
return true;
710710

711+
// Declaration marked as `@_alwaysEmitIntoClient` that
712+
// returns opaque result type with availability conditions
713+
// has to be kept alive to emit opaque type metadata descriptor.
714+
if (markedAsAlwaysEmitIntoClient() &&
715+
hasOpaqueResultTypeWithAvailabilityConditions())
716+
return true;
717+
711718
return swift::isPossiblyUsedExternally(linkage, getModule().isWholeModule());
712719
}
713720

0 commit comments

Comments
 (0)