Skip to content

Commit b76f1db

Browse files
authored
Merge pull request swiftlang#20094 from slavapestov/fix-noassert-class-metadata
Runtime: Unconditionally realize superclass metadata in swift_updateClassMetadata()
2 parents e58a6aa + 4d69e6f commit b76f1db

File tree

2 files changed

+32
-31
lines changed

2 files changed

+32
-31
lines changed

stdlib/public/runtime/Metadata.cpp

Lines changed: 21 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2637,41 +2637,31 @@ swift::swift_updateClassMetadata(ClassMetadata *self,
26372637
// though our superclass field references it statically.
26382638
const ClassMetadata *super = nullptr;
26392639

2640-
// In assert builds, realize the superclass metadata even if we're
2641-
// on an older runtime.
2642-
#ifndef NDEBUG
2643-
bool realizeSuperclass = true;
2644-
#else
2645-
bool realizeSuperclass = requiresUpdate;
2646-
#endif
2647-
2648-
if (realizeSuperclass) {
2649-
if (auto superclassNameBase = self->getDescription()->SuperclassType.get()) {
2650-
StringRef superclassName =
2651-
Demangle::makeSymbolicMangledNameStringRef(superclassNameBase);
2652-
SubstGenericParametersFromMetadata substitutions(self);
2653-
const Metadata *superclass =
2654-
_getTypeByMangledName(superclassName, substitutions);
2655-
if (!superclass) {
2656-
fatalError(0,
2657-
"failed to demangle superclass of %s from mangled name '%s'\n",
2658-
self->getDescription()->Name.get(),
2659-
superclassName.str().c_str());
2660-
}
2661-
2662-
if (auto objcWrapper = dyn_cast<ObjCClassWrapperMetadata>(superclass))
2663-
superclass = objcWrapper->Class;
2664-
2665-
super = cast<ClassMetadata>(superclass);
2640+
if (auto superclassNameBase = self->getDescription()->SuperclassType.get()) {
2641+
StringRef superclassName =
2642+
Demangle::makeSymbolicMangledNameStringRef(superclassNameBase);
2643+
SubstGenericParametersFromMetadata substitutions(self);
2644+
const Metadata *superclass =
2645+
_getTypeByMangledName(superclassName, substitutions);
2646+
if (!superclass) {
2647+
fatalError(0,
2648+
"failed to demangle superclass of %s from mangled name '%s'\n",
2649+
self->getDescription()->Name.get(),
2650+
superclassName.str().c_str());
26662651
}
26672652

2668-
// Check that it matches what's already in there.
2669-
if (!super)
2670-
assert(self->Superclass == getRootSuperclass());
2671-
else
2672-
assert(self->Superclass == super);
2653+
if (auto objcWrapper = dyn_cast<ObjCClassWrapperMetadata>(superclass))
2654+
superclass = objcWrapper->Class;
2655+
2656+
super = cast<ClassMetadata>(superclass);
26732657
}
26742658

2659+
// Check that it matches what's already in there.
2660+
if (!super)
2661+
assert(self->Superclass == getRootSuperclass());
2662+
else
2663+
assert(self->Superclass == super);
2664+
26752665
(void) super;
26762666

26772667
// If we're running on a older Objective-C runtime, just realize

test/Interpreter/objc_class_resilience.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,15 @@ ResilientClassTestSuite.test("Category") {
3838
expectEqual(42, takesMyProtocol(ResilientFieldWithCategory()))
3939
}
4040

41+
// rdar://problem/45569020 - Make sure we initialize the superclass first
42+
class ResilientSuperclass {
43+
var value: ResilientInt?
44+
}
45+
46+
class ResilientSubclass : ResilientSuperclass {}
47+
48+
ResilientClassTestSuite.test("Superclass") {
49+
_blackHole(ResilientSubclass())
50+
}
51+
4152
runAllTests()

0 commit comments

Comments
 (0)