Skip to content

Commit 2846fa6

Browse files
committed
IRGen: Fix for categories on resilient classes from other modules
If a class has resilient metadata from our point of view, it might still not have a class stub, if its entire inheritance chain is defined in a single module. Note that inserting a superclass is still a resilient operation; the only way to change a class from having static metadata to having a class stub is to change it's root class, which is not something we can do resiliently.
1 parent aa77f6e commit 2846fa6

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

lib/IRGen/MetadataRequest.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -522,14 +522,26 @@ irgen::tryEmitConstantHeapMetadataRef(IRGenModule &IGM,
522522
auto theDecl = type->getClassOrBoundGenericClass();
523523
assert(theDecl && "emitting constant heap metadata ref for non-class type?");
524524

525-
switch (IGM.getClassMetadataStrategy(theDecl)) {
526-
case ClassMetadataStrategy::Resilient:
525+
// Note that getClassMetadataStrategy() will return
526+
// ClassMetadataStrategy::Resilient if the class is
527+
// from another resilience domain, even if inside that
528+
// resilience domain the class has fixed metadata
529+
// layout.
530+
//
531+
// Since a class only has a class stub if its class
532+
// hierarchy crosses resilience domains, we use a
533+
// slightly different query here.
534+
if (theDecl->checkAncestry(AncestryFlags::ResilientOther)) {
527535
if (allowStub && IGM.Context.LangOpts.EnableObjCResilientClassStubs) {
528536
return IGM.getAddrOfObjCResilientClassStub(theDecl, NotForDefinition,
529537
TypeMetadataAddress::AddressPoint);
530538
}
539+
531540
return nullptr;
541+
}
532542

543+
switch (IGM.getClassMetadataStrategy(theDecl)) {
544+
case ClassMetadataStrategy::Resilient:
533545
case ClassMetadataStrategy::Singleton:
534546
if (!allowDynamicUninitialized)
535547
return nullptr;

test/IRGen/class_update_callback_with_stub.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ import resilient_objc_class
9191
// CHECK-LABEL: @"_CATEGORY__TtC31class_update_callback_with_stub27FixedLayoutNSObjectSubclass_$_class_update_callback_with_stub" = private constant
9292
// CHECK-SAME: @"$s31class_update_callback_with_stub27FixedLayoutNSObjectSubclassCMs"
9393

94+
// -- But not if the entire inheritance chain is in a single module
95+
96+
// CHECK-LABEL: @"_CATEGORY__TtC15resilient_class22ResilientOutsideParent_$_class_update_callback_with_stub" = private constant
97+
// CHECK-SAME: @"$s15resilient_class22ResilientOutsideParentCN"
98+
9499

95100
// -- Class stubs do not appear in the class list
96101

@@ -102,6 +107,7 @@ import resilient_objc_class
102107
// CHECK-SAME: @"_CATEGORY__TtC31class_update_callback_with_stub17ResilientSubclass_$_class_update_callback_with_stub"
103108
// CHECK-SAME: @"_CATEGORY__TtC31class_update_callback_with_stub25ResilientNSObjectSubclass_$_class_update_callback_with_stub"
104109
// CHECK-SAME: @"_CATEGORY__TtC31class_update_callback_with_stub27FixedLayoutNSObjectSubclass_$_class_update_callback_with_stub"
110+
// CHECK-SAME: @"_CATEGORY__TtC15resilient_class22ResilientOutsideParent_$_class_update_callback_with_stub"
105111
// CHECK-SAME: , section "__DATA,__objc_catlist,regular,no_dead_strip"
106112

107113

@@ -153,3 +159,7 @@ extension ResilientNSObjectSubclass {
153159
extension FixedLayoutNSObjectSubclass {
154160
@objc public func objcMethod() {}
155161
}
162+
163+
extension ResilientOutsideParent {
164+
@objc public func anObjcMethod() {}
165+
}

0 commit comments

Comments
 (0)