Skip to content

Commit 9499d1d

Browse files
authored
Merge pull request #20173 from slavapestov/weak-linked
IRGen: Use @_weakLinked to test backward deployment of resilient protocols
2 parents 8d1ac7b + 57979d1 commit 9499d1d

File tree

10 files changed

+164
-70
lines changed

10 files changed

+164
-70
lines changed

include/swift/AST/Attr.def

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -359,9 +359,8 @@ DECL_ATTR(_clangImporterSynthesizedType, ClangImporterSynthesizedType,
359359
LongAttribute | RejectByParser | UserInaccessible |
360360
NotSerialized, 74)
361361
SIMPLE_DECL_ATTR(_weakLinked, WeakLinked,
362-
OnNominalType | OnFunc | OnAccessor | OnVar | OnSubscript | OnConstructor |
363-
OnEnumElement |
364-
UserInaccessible,
362+
OnNominalType | OnAssociatedType | OnFunc | OnAccessor | OnVar |
363+
OnSubscript | OnConstructor | OnEnumElement | UserInaccessible,
365364
75)
366365
SIMPLE_DECL_ATTR(_frozen, Frozen,
367366
OnEnum |

include/swift/IRGen/Linking.h

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -919,23 +919,7 @@ class LinkEntity {
919919
}
920920

921921
/// Determine whether this entity will be weak-imported.
922-
bool isWeakImported(ModuleDecl *module) const {
923-
if (getKind() == Kind::SILGlobalVariable &&
924-
getSILGlobalVariable()->getDecl())
925-
return getSILGlobalVariable()->getDecl()->isWeakImported(module);
926-
927-
if (getKind() == Kind::SILFunction) {
928-
if (auto clangOwner = getSILFunction()->getClangNodeOwner())
929-
return clangOwner->isWeakImported(module);
930-
if (getSILFunction()->isWeakLinked())
931-
return getSILFunction()->isAvailableExternally();
932-
}
933-
934-
if (!isDeclKind(getKind()))
935-
return false;
936-
937-
return getDecl()->isWeakImported(module);
938-
}
922+
bool isWeakImported(ModuleDecl *module) const;
939923

940924
/// Return the source file whose codegen should trigger emission of this
941925
/// link entity, if one can be identified.

lib/AST/Decl.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,12 @@ bool Decl::isWeakImported(ModuleDecl *fromModule) const {
551551
if (getAttrs().hasAttribute<WeakLinkedAttr>())
552552
return true;
553553

554+
if (auto *accessor = dyn_cast<AccessorDecl>(this))
555+
return accessor->getStorage()->isWeakImported(fromModule);
556+
557+
if (auto *dtor = dyn_cast<DestructorDecl>(this))
558+
return cast<ClassDecl>(dtor->getDeclContext())->isWeakImported(fromModule);
559+
554560
// FIXME: Also check availability when containingModule is resilient.
555561
return false;
556562
}

lib/IRGen/Linking.cpp

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,94 @@ Alignment LinkEntity::getAlignment(IRGenModule &IGM) const {
763763
}
764764
}
765765

766+
bool LinkEntity::isWeakImported(ModuleDecl *module) const {
767+
switch (getKind()) {
768+
case Kind::SILGlobalVariable:
769+
if (getSILGlobalVariable()->getDecl())
770+
return getSILGlobalVariable()->getDecl()->isWeakImported(module);
771+
return false;
772+
773+
case Kind::SILFunction: {
774+
// For imported functions check the Clang declaration.
775+
if (auto clangOwner = getSILFunction()->getClangNodeOwner())
776+
return clangOwner->isWeakImported(module);
777+
778+
// For native functions check a flag on the SILFunction
779+
// itself.
780+
if (getSILFunction()->isWeakLinked())
781+
return getSILFunction()->isAvailableExternally();
782+
return false;
783+
}
784+
785+
case Kind::AssociatedConformanceDescriptor:
786+
case Kind::DefaultAssociatedConformanceAccessor: {
787+
// Associated conformance descriptors use the protocol as
788+
// their declaration, but are weak linked if the associated
789+
// type stored in extra storage area is weak linked.
790+
auto assocConformance = getAssociatedConformance();
791+
auto *depMemTy = assocConformance.first->castTo<DependentMemberType>();
792+
return depMemTy->getAssocType()->isWeakImported(module);
793+
}
794+
795+
case Kind::TypeMetadata:
796+
case Kind::TypeMetadataAccessFunction: {
797+
if (auto *nominalDecl = getType()->getAnyNominal())
798+
return nominalDecl->isWeakImported(module);
799+
return false;
800+
}
801+
802+
case Kind::DispatchThunk:
803+
case Kind::DispatchThunkInitializer:
804+
case Kind::DispatchThunkAllocator:
805+
case Kind::MethodDescriptor:
806+
case Kind::MethodDescriptorInitializer:
807+
case Kind::MethodDescriptorAllocator:
808+
case Kind::MethodLookupFunction:
809+
case Kind::EnumCase:
810+
case Kind::FieldOffset:
811+
case Kind::ObjCClass:
812+
case Kind::ObjCClassRef:
813+
case Kind::ObjCMetaclass:
814+
case Kind::SwiftMetaclassStub:
815+
case Kind::ObjCMetadataUpdateFunction:
816+
case Kind::ClassMetadataBaseOffset:
817+
case Kind::PropertyDescriptor:
818+
case Kind::NominalTypeDescriptor:
819+
case Kind::ModuleDescriptor:
820+
case Kind::ProtocolDescriptor:
821+
case Kind::ProtocolRequirementsBaseDescriptor:
822+
case Kind::AssociatedTypeDescriptor:
823+
return getDecl()->isWeakImported(module);
824+
825+
// TODO: Revisit some of the below, for weak conformances.
826+
case Kind::TypeMetadataPattern:
827+
case Kind::TypeMetadataInstantiationCache:
828+
case Kind::TypeMetadataInstantiationFunction:
829+
case Kind::TypeMetadataSingletonInitializationCache:
830+
case Kind::TypeMetadataCompletionFunction:
831+
case Kind::ExtensionDescriptor:
832+
case Kind::AnonymousDescriptor:
833+
case Kind::DirectProtocolWitnessTable:
834+
case Kind::ProtocolWitnessTablePattern:
835+
case Kind::GenericProtocolWitnessTableInstantiationFunction:
836+
case Kind::AssociatedTypeWitnessTableAccessFunction:
837+
case Kind::ReflectionAssociatedTypeDescriptor:
838+
case Kind::ProtocolConformanceDescriptor:
839+
case Kind::ProtocolWitnessTableLazyAccessFunction:
840+
case Kind::ProtocolWitnessTableLazyCacheVariable:
841+
case Kind::ValueWitness:
842+
case Kind::ValueWitnessTable:
843+
case Kind::TypeMetadataLazyCacheVariable:
844+
case Kind::ForeignTypeMetadataCandidate:
845+
case Kind::ReflectionBuiltinDescriptor:
846+
case Kind::ReflectionFieldDescriptor:
847+
case Kind::CoroutineContinuationPrototype:
848+
return false;
849+
}
850+
851+
llvm_unreachable("Bad link entity kind");
852+
}
853+
766854
const SourceFile *LinkEntity::getSourceFileForEmission() const {
767855
const SourceFile *sf;
768856

lib/SIL/SILFunctionBuilder.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,6 @@ static void addFunctionAttributes(SILFunction *F, DeclAttributes &Attrs,
5757
// @_silgen_name and @_cdecl functions may be called from C code somewhere.
5858
if (Attrs.hasAttribute<SILGenNameAttr>() || Attrs.hasAttribute<CDeclAttr>())
5959
F->setHasCReferences(true);
60-
61-
if (Attrs.hasAttribute<WeakLinkedAttr>())
62-
F->setWeakLinked();
6360
}
6461

6562
SILFunction *
@@ -115,6 +112,9 @@ SILFunctionBuilder::getOrCreateFunction(SILLocation loc, SILDeclRef constant,
115112
if (constant.isForeign && decl->hasClangNode())
116113
F->setClangNodeOwner(decl);
117114

115+
if (decl->isWeakImported(/*fromModule=*/nullptr))
116+
F->setWeakLinked();
117+
118118
if (auto *accessor = dyn_cast<AccessorDecl>(decl)) {
119119
auto *storage = accessor->getStorage();
120120
// Add attributes for e.g. computed properties.

test/IRGen/Inputs/weak_import_native_helper.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,15 @@ public enum GenericE<T> {}
103103

104104
@_weakLinked
105105
open class GenericC<T> {}
106+
107+
public protocol OtherProtocol {}
108+
public struct ConcreteType : OtherProtocol {}
109+
110+
public protocol ProtocolWithWeakMembers {
111+
@_weakLinked associatedtype T : OtherProtocol = ConcreteType
112+
@_weakLinked func f()
113+
}
114+
115+
extension ProtocolWithWeakMembers {
116+
@_weakLinked public func f() {}
117+
}

test/IRGen/weak_import_native.swift

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55

66
import weak_import_native_helper
77

8+
// CHECK-DAG: @"$s25weak_import_native_helper23ProtocolWithWeakMembersP1TAC_AA05OtherE0Tn" = extern_weak global %swift.protocol_requirement
9+
// CHECK-DAG: @"$s1T25weak_import_native_helper23ProtocolWithWeakMembersPTl" = extern_weak global %swift.protocol_requirement
10+
// CHECK-DAG: @"$s25weak_import_native_helper23ProtocolWithWeakMembersP1fyyFTq" = extern_weak global %swift.method_descriptor
11+
// CHECK-DAG: declare extern_weak swiftcc void @"$s25weak_import_native_helper23ProtocolWithWeakMembersPAAE1fyyF"(%swift.type*, i8**, %swift.opaque* noalias nocapture swiftself)
12+
struct ConformsToProtocolWithWeakMembers : ProtocolWithWeakMembers {}
13+
814
func testTopLevel() {
915
// CHECK-DAG: declare extern_weak {{.+}} @"$s25weak_import_native_helper2fnyyF"()
1016
fn()
@@ -52,10 +58,16 @@ func testStruct() {
5258
}
5359

5460
func testEnum() {
55-
// FIXME: We're still referencing tags directly.
61+
// CHECK-DAG: @"$s25weak_import_native_helper1EO6strongyA2CmFWC" = external constant i32
5662
_ = E.strong
63+
64+
// CHECK-DAG: @"$s25weak_import_native_helper1EO0A0yA2CmFWC" = extern_weak constant i32
5765
_ = E.weak
66+
67+
// CHECK-DAG: @"$s25weak_import_native_helper1EO11strongAssocyACSicACmFWC" = external constant i32
5868
_ = E.strongAssoc(0)
69+
70+
// CHECK-DAG: @"$s25weak_import_native_helper1EO0A5AssocyACSicACmFWC" = extern_weak constant i32
5971
_ = E.weakAssoc(0)
6072
}
6173

@@ -66,25 +78,23 @@ func testClass() {
6678
// CHECK-DAG: declare extern_weak {{.+}} @"$s25weak_import_native_helper1CC2fnyyFTj"
6779
c.fn()
6880

69-
// FIXME: vtable dispatch functions for accessors should also be weak
70-
71-
// CHECK-DAG: declare swiftcc {{.+}} @"$s25weak_import_native_helper1CC10storedPropSivgTj"
72-
// CHECK-DAG: declare swiftcc {{.+}} @"$s25weak_import_native_helper1CC10storedPropSivsTj"
73-
// CHECK-DAG: declare swiftcc {{.+}} @"$s25weak_import_native_helper1CC10storedPropSivMTj"
81+
// CHECK-DAG: declare extern_weak swiftcc {{.+}} @"$s25weak_import_native_helper1CC10storedPropSivgTj"
82+
// CHECK-DAG: declare extern_weak swiftcc {{.+}} @"$s25weak_import_native_helper1CC10storedPropSivsTj"
83+
// CHECK-DAG: declare extern_weak swiftcc {{.+}} @"$s25weak_import_native_helper1CC10storedPropSivMTj"
7484
let x = c.storedProp
7585
c.storedProp = x
7686
c.storedProp += 1
7787

78-
// CHECK-DAG: declare swiftcc {{.+}} @"$s25weak_import_native_helper1CC12computedPropSivgTj"
79-
// CHECK-DAG: declare swiftcc {{.+}} @"$s25weak_import_native_helper1CC12computedPropSivsTj"
80-
// CHECK-DAG: declare swiftcc {{.+}} @"$s25weak_import_native_helper1CC12computedPropSivMTj"
88+
// CHECK-DAG: declare extern_weak swiftcc {{.+}} @"$s25weak_import_native_helper1CC12computedPropSivgTj"
89+
// CHECK-DAG: declare extern_weak swiftcc {{.+}} @"$s25weak_import_native_helper1CC12computedPropSivsTj"
90+
// CHECK-DAG: declare extern_weak swiftcc {{.+}} @"$s25weak_import_native_helper1CC12computedPropSivMTj"
8191
let y = c.computedProp
8292
c.computedProp = y
8393
c.computedProp += 1
8494

85-
// CHECK-DAG: declare swiftcc {{.+}} @"$s25weak_import_native_helper1CCyS2icigTj"
86-
// CHECK-DAG: declare swiftcc {{.+}} @"$s25weak_import_native_helper1CCyS2icisTj"
87-
// CHECK-DAG: declare swiftcc {{.+}} @"$s25weak_import_native_helper1CCyS2iciMTj"
95+
// CHECK-DAG: declare extern_weak swiftcc {{.+}} @"$s25weak_import_native_helper1CCyS2icigTj"
96+
// CHECK-DAG: declare extern_weak swiftcc {{.+}} @"$s25weak_import_native_helper1CCyS2icisTj"
97+
// CHECK-DAG: declare extern_weak swiftcc {{.+}} @"$s25weak_import_native_helper1CCyS2iciMTj"
8898
let z = c[0]
8999
c[0] = z
90100
c[0] += 1
@@ -104,18 +114,16 @@ func testProtocolExistential(_ p: P) {
104114
// CHECK-DAG: declare extern_weak {{.+}} @"$s25weak_import_native_helper1PP2fnyyFTj"
105115
p.fn()
106116

107-
// FIXME: witness table dispatch functions for accessors should also be weak
108-
109-
// CHECK-DAG: declare swiftcc {{.+}} @"$s25weak_import_native_helper1PP4propSivgTj"
110-
// CHECK-DAG: declare swiftcc {{.+}} @"$s25weak_import_native_helper1PP4propSivsTj"
111-
// CHECK-DAG: declare swiftcc {{.+}} @"$s25weak_import_native_helper1PP4propSivMTj"
117+
// CHECK-DAG: declare extern_weak swiftcc {{.+}} @"$s25weak_import_native_helper1PP4propSivgTj"
118+
// CHECK-DAG: declare extern_weak swiftcc {{.+}} @"$s25weak_import_native_helper1PP4propSivsTj"
119+
// CHECK-DAG: declare extern_weak swiftcc {{.+}} @"$s25weak_import_native_helper1PP4propSivMTj"
112120
let x = p.prop
113121
mutP.prop = x
114122
mutP.prop += 1
115123

116-
// CHECK-DAG: declare swiftcc {{.+}} @"$s25weak_import_native_helper1PPyS2icigTj"
117-
// CHECK-DAG: declare swiftcc {{.+}} @"$s25weak_import_native_helper1PPyS2icisTj"
118-
// CHECK-DAG: declare swiftcc {{.+}} @"$s25weak_import_native_helper1PPyS2iciMTj"
124+
// CHECK-DAG: declare extern_weak swiftcc {{.+}} @"$s25weak_import_native_helper1PPyS2icigTj"
125+
// CHECK-DAG: declare extern_weak swiftcc {{.+}} @"$s25weak_import_native_helper1PPyS2icisTj"
126+
// CHECK-DAG: declare extern_weak swiftcc {{.+}} @"$s25weak_import_native_helper1PPyS2iciMTj"
119127
let z = p[0]
120128
mutP[0] = z
121129
mutP[0] += 1
@@ -137,27 +145,24 @@ func testProtocolGeneric<Impl: P>(_ type: Impl.Type) {
137145
}
138146

139147
func testWeakTypes() -> [Any.Type] {
140-
// FIXME: These should be weak.
141-
// CHECK-DAG: declare swiftcc %swift.metadata_response @"$s25weak_import_native_helper5WeakSVMa"
142-
// CHECK-DAG: declare swiftcc %swift.metadata_response @"$s25weak_import_native_helper5WeakEOMa"
143-
// CHECK-DAG: declare swiftcc %swift.metadata_response @"$s25weak_import_native_helper5WeakCCMa"
148+
// CHECK-DAG: declare extern_weak swiftcc %swift.metadata_response @"$s25weak_import_native_helper5WeakSVMa"
149+
// CHECK-DAG: declare extern_weak swiftcc %swift.metadata_response @"$s25weak_import_native_helper5WeakEOMa"
150+
// CHECK-DAG: declare extern_weak swiftcc %swift.metadata_response @"$s25weak_import_native_helper5WeakCCMa"
144151
// CHECK-DAG: @"$s25weak_import_native_helper5WeakPMp" = extern_weak global %swift.protocol
145-
// CHECK-DAG: declare swiftcc %swift.metadata_response @"$s25weak_import_native_helper8GenericSVMa"
146-
// CHECK-DAG: declare swiftcc %swift.metadata_response @"$s25weak_import_native_helper8GenericEOMa"
147-
// CHECK-DAG: declare swiftcc %swift.metadata_response @"$s25weak_import_native_helper8GenericCCMa"
152+
// CHECK-DAG: declare extern_weak swiftcc %swift.metadata_response @"$s25weak_import_native_helper8GenericSVMa"
153+
// CHECK-DAG: declare extern_weak swiftcc %swift.metadata_response @"$s25weak_import_native_helper8GenericEOMa"
154+
// CHECK-DAG: declare extern_weak swiftcc %swift.metadata_response @"$s25weak_import_native_helper8GenericCCMa"
148155
return [WeakS.self, WeakE.self, WeakC.self, WeakP.self, GenericS<Int>.self, GenericE<Int>.self, GenericC<Int>.self]
149156
}
150157

151158
class WeakSub: WeakC {
152159
deinit {
153-
// FIXME: This should be weak.
154-
// CHECK-DAG: declare swiftcc {{.+}} @"$s25weak_import_native_helper5WeakCCfd"
160+
// CHECK-DAG: declare extern_weak swiftcc {{.+}} @"$s25weak_import_native_helper5WeakCCfd"
155161
}
156162
}
157163

158164
class WeakGenericSub: GenericC<Int> {
159165
deinit {
160-
// FIXME: This should be weak.
161-
// CHECK-DAG: declare swiftcc {{.+}} @"$s25weak_import_native_helper8GenericCCfd"
166+
// CHECK-DAG: declare extern_weak swiftcc {{.+}} @"$s25weak_import_native_helper8GenericCCfd"
162167
}
163168
}

0 commit comments

Comments
 (0)