Skip to content

Commit 76dd00b

Browse files
author
Harlan Haskins
committed
[Demangle] Check for old-style mangling in getObjCClassByMangledName
This caused an issue where the runtime was unable to find subclasses of resilient subclasses of NSObject until they were first registered by their sugared name with NSClassFromString or were instantiated directly. rdar://48892003
1 parent bdd3695 commit 76dd00b

File tree

1 file changed

+22
-3
lines changed

1 file changed

+22
-3
lines changed

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1422,9 +1422,28 @@ static objc_hook_getClass OldGetClassHook;
14221422
static BOOL
14231423
getObjCClassByMangledName(const char * _Nonnull typeName,
14241424
Class _Nullable * _Nonnull outClass) {
1425-
auto metadata = swift_getTypeByMangledNameInEnvironment(typeName, strlen(typeName),
1426-
/* no substitutions */
1427-
nullptr, nullptr);
1425+
// Demangle old-style class and protocol names, which are still used in the
1426+
// ObjC metadata.
1427+
StringRef typeStr(typeName);
1428+
const Metadata *metadata = nullptr;
1429+
if (typeStr.startswith("_Tt")) {
1430+
Demangler demangler;
1431+
auto node = demangler.demangleSymbol(typeName);
1432+
if (!node)
1433+
return NO;
1434+
metadata = swift_getTypeByMangledNode(
1435+
MetadataState::Complete, demangler, node,
1436+
/* no substitutions */
1437+
[&](unsigned depth, unsigned index) {
1438+
return nullptr;
1439+
},
1440+
[&](const Metadata *type, unsigned index) {
1441+
return nullptr;
1442+
}).getMetadata();
1443+
} else {
1444+
metadata = swift_getTypeByMangledNameInEnvironment(
1445+
typeStr.data(), typeStr.size(), /* no substitutions */ nullptr, nullptr);
1446+
}
14281447
if (metadata) {
14291448
auto objcClass =
14301449
reinterpret_cast<Class>(

0 commit comments

Comments
 (0)