Skip to content

Commit 42a36ac

Browse files
committed
Fix the demangling of sending result types when combined with isolation
Fixes the immediate problem, but the presence of demangling code in the runtime means that we'll need a follow-up to fix the compiler so that it doesn't try to use the demangler to materialize metadata for function types that have both isolation and a sending result. rdar://142443925
1 parent 9d95d2c commit 42a36ac

File tree

7 files changed

+82
-28
lines changed

7 files changed

+82
-28
lines changed

docs/ABI/Mangling.rst

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -732,10 +732,12 @@ Types
732732
FUNCTION-KIND ::= 'A' // @auto_closure function type (escaping)
733733
FUNCTION-KIND ::= 'E' // function type (noescape)
734734

735-
C-TYPE is mangled according to the Itanium ABI, and prefixed with the length.
736-
Non-ASCII identifiers are preserved as-is; we do not use Punycode.
735+
C-TYPE ::= NATURAL CHAR* // raw Itanium mangling
737736

738-
function-signature ::= params-type params-type async? sendable? throws? differentiable? function-isolation? // results and parameters
737+
function-signature ::= result-type params-type async? sendable? throws? differentiable? function-isolation? sending-result? // results and parameters
738+
739+
result-type ::= type
740+
result-type ::= empty-list // shortcut for ()
739741

740742
params-type ::= type 'z'? 'h'? // tuple in case of multiple parameters or a single parameter with a single tuple type
741743
// with optional inout convention, shared convention. parameters don't have labels,
@@ -751,6 +753,7 @@ Types
751753
#if SWIFT_RUNTIME_VERSION >= 6.0
752754
throws ::= type 'YK' // 'throws(type)' annotation on function types
753755
function-isolation ::= type 'YA' // @isolated(any) on function type
756+
sending-result ::= 'YT' // -> sending T
754757
#endif
755758
differentiable ::= 'Yjf' // @differentiable(_forward) on function type
756759
differentiable ::= 'Yjr' // @differentiable(reverse) on function type
@@ -762,6 +765,12 @@ Types
762765
// FIXME: Consider replacing 'h' with a two-char code
763766
list-type ::= type identifier? 'Yk'? 'z'? 'h'? 'n'? 'Yi'? 'd'? 'Yt'? // type with optional label, '@noDerivative', inout convention, shared convention, owned convention, actor 'isolated', variadic specifier, and compile-time constant
764767

768+
In the mangling of C function types,``C-TYPE`` is mangled according to the Itanium ABI, prefixed with its length. This resembles the mangling of ``identifier``, but it does not honor substitutions or Punycode.
769+
770+
The 6.0 Swift runtime supports demangling ``sending-result``, but has a bug when it's combined with ``function-isolation``.
771+
772+
::
773+
765774
METATYPE-REPR ::= 't' // Thin metatype representation
766775
METATYPE-REPR ::= 'T' // Thick metatype representation
767776
METATYPE-REPR ::= 'o' // ObjC metatype representation

include/swift/Demangling/TypeDecoder.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -915,6 +915,12 @@ class TypeDecoder {
915915
++firstChildIdx;
916916
}
917917

918+
if (Node->getChild(firstChildIdx)->getKind() ==
919+
NodeKind::SendingResultFunctionType) {
920+
extFlags = extFlags.withSendingResult();
921+
++firstChildIdx;
922+
}
923+
918924
BuiltType globalActorType = BuiltType();
919925
if (Node->getChild(firstChildIdx)->getKind() ==
920926
NodeKind::GlobalActorFunctionType) {
@@ -937,12 +943,6 @@ class TypeDecoder {
937943
++firstChildIdx;
938944
}
939945

940-
if (Node->getChild(firstChildIdx)->getKind() ==
941-
NodeKind::SendingResultFunctionType) {
942-
extFlags = extFlags.withSendingResult();
943-
++firstChildIdx;
944-
}
945-
946946
FunctionMetadataDifferentiabilityKind diffKind;
947947
if (Node->getChild(firstChildIdx)->getKind() ==
948948
NodeKind::DifferentiableFunctionType) {

lib/Demangling/Demangler.cpp

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1628,24 +1628,51 @@ NodePointer Demangler::demanglePlainFunction() {
16281628

16291629
NodePointer Demangler::popFunctionType(Node::Kind kind, bool hasClangType) {
16301630
NodePointer FuncType = createNode(kind);
1631+
1632+
// Demangle a C function type if the function node kind says that
1633+
// one follows.
16311634
NodePointer ClangType = nullptr;
16321635
if (hasClangType) {
16331636
ClangType = demangleClangType();
16341637
}
16351638
addChild(FuncType, ClangType);
1636-
addChild(FuncType, popNode(Node::Kind::GlobalActorFunctionType));
1637-
addChild(FuncType, popNode(Node::Kind::IsolatedAnyFunctionType));
1639+
1640+
// The components of function-signature. Note that these need to be
1641+
// popped in the reverse of the order they're mangled. If you add a
1642+
// new component, be sure to add a demangling test case for combinations
1643+
// of specifiers.
1644+
1645+
// sending-result?
16381646
addChild(FuncType, popNode(Node::Kind::SendingResultFunctionType));
1647+
1648+
// function-isolation?
1649+
auto isFunctionIsolation = [](Node::Kind kind) {
1650+
return kind == Node::Kind::GlobalActorFunctionType ||
1651+
kind == Node::Kind::IsolatedAnyFunctionType;
1652+
};
1653+
addChild(FuncType, popNode(isFunctionIsolation));
1654+
1655+
// differentiable?
16391656
addChild(FuncType, popNode(Node::Kind::DifferentiableFunctionType));
1657+
1658+
// throws?
16401659
addChild(FuncType, popNode([](Node::Kind kind) {
16411660
return kind == Node::Kind::ThrowsAnnotation ||
16421661
kind == Node::Kind::TypedThrowsAnnotation;
16431662
}));
1663+
1664+
// sendable?
16441665
addChild(FuncType, popNode(Node::Kind::ConcurrentFunctionType));
1666+
1667+
// async?
16451668
addChild(FuncType, popNode(Node::Kind::AsyncAnnotation));
16461669

1670+
// params-type
16471671
FuncType = addChild(FuncType, popFunctionParams(Node::Kind::ArgumentTuple));
1672+
1673+
// result-type
16481674
FuncType = addChild(FuncType, popFunctionParams(Node::Kind::ReturnType));
1675+
16491676
return createType(FuncType);
16501677
}
16511678

@@ -1675,15 +1702,15 @@ NodePointer Demangler::popFunctionParamLabels(NodePointer Type) {
16751702
return nullptr;
16761703

16771704
unsigned FirstChildIdx = 0;
1705+
if (FuncType->getChild(FirstChildIdx)->getKind() ==
1706+
Node::Kind::SendingResultFunctionType)
1707+
++FirstChildIdx;
16781708
if (FuncType->getChild(FirstChildIdx)->getKind()
16791709
== Node::Kind::GlobalActorFunctionType)
16801710
++FirstChildIdx;
16811711
if (FuncType->getChild(FirstChildIdx)->getKind()
16821712
== Node::Kind::IsolatedAnyFunctionType)
16831713
++FirstChildIdx;
1684-
if (FuncType->getChild(FirstChildIdx)->getKind() ==
1685-
Node::Kind::SendingResultFunctionType)
1686-
++FirstChildIdx;
16871714
if (FuncType->getChild(FirstChildIdx)->getKind()
16881715
== Node::Kind::DifferentiableFunctionType)
16891716
++FirstChildIdx;

lib/Demangling/NodePrinter.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,18 @@ class NodePrinter {
898898
// handled earlier
899899
++startIndex;
900900
}
901+
902+
// Be sure to check for function signature components in the same
903+
// order that they're added by the demangler, which is the reverse
904+
// of the order that they appear in the mangling grammar.
905+
906+
if (node->getChild(startIndex)->getKind() ==
907+
Node::Kind::SendingResultFunctionType) {
908+
++startIndex;
909+
hasSendingResult = true;
910+
}
911+
912+
// function-isolation; note that these can't actually both appear.
901913
if (node->getChild(startIndex)->getKind()
902914
== Node::Kind::IsolatedAnyFunctionType) {
903915
print(node->getChild(startIndex), depth + 1);
@@ -908,6 +920,7 @@ class NodePrinter {
908920
print(node->getChild(startIndex), depth + 1);
909921
++startIndex;
910922
}
923+
911924
if (node->getChild(startIndex)->getKind() ==
912925
Node::Kind::DifferentiableFunctionType) {
913926
diffKind =
@@ -932,11 +945,6 @@ class NodePrinter {
932945
++startIndex;
933946
isAsync = true;
934947
}
935-
if (node->getChild(startIndex)->getKind() ==
936-
Node::Kind::SendingResultFunctionType) {
937-
++startIndex;
938-
hasSendingResult = true;
939-
}
940948

941949
switch (diffKind) {
942950
case MangledDifferentiabilityKind::Forward:

stdlib/public/RemoteInspection/TypeRef.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,15 @@ class DemanglingForTypeRef
766766

767767
auto funcNode = Dem.createNode(kind);
768768

769+
// This needs to use the same order as the demangler.
770+
771+
// TODO: the C function type would go here
772+
773+
if (F->getExtFlags().hasSendingResult()) {
774+
auto node = Dem.createNode(Node::Kind::SendingResultFunctionType);
775+
funcNode->addChild(node, Dem);
776+
}
777+
769778
if (auto globalActor = F->getGlobalActor()) {
770779
auto node = Dem.createNode(Node::Kind::GlobalActorFunctionType);
771780
auto globalActorNode = visit(globalActor);
@@ -774,9 +783,6 @@ class DemanglingForTypeRef
774783
} else if (F->getExtFlags().isIsolatedAny()) {
775784
auto node = Dem.createNode(Node::Kind::IsolatedAnyFunctionType);
776785
funcNode->addChild(node, Dem);
777-
} else if (F->getExtFlags().hasSendingResult()) {
778-
auto node = Dem.createNode(Node::Kind::SendingResultFunctionType);
779-
funcNode->addChild(node, Dem);
780786
}
781787

782788
if (F->getFlags().isDifferentiable()) {

stdlib/public/runtime/Demangle.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -741,8 +741,14 @@ swift::_swift_buildDemanglingForMetadata(const Metadata *type,
741741

742742
NodePointer result = Dem.createNode(Node::Kind::ReturnType);
743743
result->addChild(resultTy, Dem);
744-
744+
745745
auto funcNode = Dem.createNode(kind);
746+
// Add the components of the function-signature production in the same
747+
// order that the demangler would.
748+
// TODO: C function type would go here
749+
if (func->getExtendedFlags().hasSendingResult())
750+
funcNode->addChild(Dem.createNode(Node::Kind::SendingResultFunctionType),
751+
Dem);
746752
if (func->hasGlobalActor()) {
747753
auto globalActorTypeNode =
748754
_swift_buildDemanglingForMetadata(func->getGlobalActor(), Dem);
@@ -798,10 +804,6 @@ swift::_swift_buildDemanglingForMetadata(const Metadata *type,
798804
if (func->isAsync())
799805
funcNode->addChild(Dem.createNode(Node::Kind::AsyncAnnotation), Dem);
800806

801-
if (func->getExtendedFlags().hasSendingResult())
802-
funcNode->addChild(Dem.createNode(Node::Kind::SendingResultFunctionType),
803-
Dem);
804-
805807
funcNode->addChild(parameters, Dem);
806808
funcNode->addChild(result, Dem);
807809
return funcNode;

test/Demangle/Inputs/manglings.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ $sS3fIedgyywTd_D ---> @escaping @differentiable @callee_guaranteed (@unowned Swi
465465
$sS3fIedgyyTd_D ---> @escaping @differentiable @callee_guaranteed (@unowned Swift.Float, @unowned sending Swift.Float) -> (@unowned Swift.Float)
466466
$s4testA2A5KlassCyYTF ---> test.test() -> sending test.Klass
467467
$s4main5KlassCACYTcMD ---> demangling cache variable for type metadata for (main.Klass) -> sending main.Klass
468-
$s4null19transferAsyncResultAA16NonSendableKlassCyYaYTF ---> null.transferAsyncResult() -> sending null.NonSendableKlass
468+
$s4null19transferAsyncResultAA16NonSendableKlassCyYaYTF ---> null.transferAsyncResult() async -> sending null.NonSendableKlass
469469
$s4null16NonSendableKlassCIegHo_ACs5Error_pIegHTrzo_TR ---> {T:} reabstraction thunk helper from @escaping @callee_guaranteed @async () -> (@owned null.NonSendableKlass) to @escaping @callee_guaranteed @async () -> sending (@out null.NonSendableKlass, @error @owned Swift.Error)
470470
$sSRyxG15Synchronization19AtomicRepresentableABRi_zrlMc ---> protocol conformance descriptor for < where A: ~Swift.Copyable> Swift.UnsafeBufferPointer<A> : Synchronization.AtomicRepresentable in Synchronization
471471
$sSRyxG15Synchronization19AtomicRepresentableABRi0_zrlMc ---> protocol conformance descriptor for < where A: ~Swift.Escapable> Swift.UnsafeBufferPointer<A> : Synchronization.AtomicRepresentable in Synchronization
@@ -483,3 +483,5 @@ $s4mainAAyyycAA1CCFTTH ---> hop to main actor thunk of main.main(main.C) -> () -
483483

484484
$s4main6VectorVy$1_SiG ---> main.Vector<2, Swift.Int>
485485
$s$n3_SSBV ---> Builtin.FixedArray<-4, Swift.String>
486+
$s3red7MyActorC3runyxxyYaKACYcYTXEYaKlFZ ---> static red.MyActor.run<A>(@red.MyActor () async throws -> sending A) async throws -> A
487+
$s3red7MyActorC3runyxxyYaKYAYTXEYaKlFZ ---> static red.MyActor.run<A>(@isolated(any) () async throws -> sending A) async throws -> A

0 commit comments

Comments
 (0)