Skip to content

Commit 7e799e9

Browse files
committed
[rbi] Fix demangling of sending results.
The issue here is that the demangler (since we have a postfix mangling) parses parameters/results/etc and then uses earlier postfix type arguments to attach the relevant types to the parameters/results/etc. Since the flag for a sending result was placed in between the parameters and results, we get an off by one error. The reason why I originally did it this way is that part of sending was cargo culted from the autodiff parts of the mangling and parts from the async/isolated(any) part of the function type mangling. In this case, I followed the location of the autodiff part of the mangling (which is per parameter) instead of the async/isolated(any) part of the mangling (which are global flags) which is what exposed this issue. The good thing is if we eventually allow for sending to be placed on individual parameters, we can potentially eliminate seeing this patter in future versions of the ABI by just placing sending onto the parameters instead. This would additionally allow for us to eliminate this offset code by checking for the flag where it is and in such a case, just place it on each parameter as a flag. rdar://141962865
1 parent 01faf1f commit 7e799e9

File tree

3 files changed

+45
-3
lines changed

3 files changed

+45
-3
lines changed

lib/Demangling/Demangler.cpp

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2431,6 +2431,15 @@ NodePointer Demangler::demangleImplFunctionType() {
24312431
++NumTypesToAdd;
24322432
}
24332433

2434+
// NOTE: Please do not add additional function level flags here besides
2435+
// ImplSendingResult (which is remaining due to ABI reasons). If one wishes to
2436+
// place a flag, place it earlier in the mangling so that it is parsed above
2437+
// near @async (demangles from 'H').
2438+
//
2439+
// The reason why is that parameters, results, yields, and errors are
2440+
// processed backwards as if they are in a contiguous array adding to them the
2441+
// appropriate set of argument types that are our postfix parameters earlier
2442+
// in the mangling.
24342443
if (nextIf('T')) {
24352444
type->addChild(createNode(Node::Kind::ImplSendingResult), *this);
24362445
}
@@ -2461,13 +2470,27 @@ NodePointer Demangler::demangleImplFunctionType() {
24612470
if (!nextIf('_'))
24622471
return nullptr;
24632472

2473+
// Due to the place that the sending result bit was placed in the mangling and
2474+
// is expected in the tree (namely before results)... we need to make sure to
2475+
// skip over it.
2476+
//
2477+
// Our methodology is that when we detect the impl sending result, we add 1 to
2478+
// the node index so that we skip over the value. We subtract since we are
2479+
// actually updating the children backwards.
2480+
int implSendingResultIndexAdjustment = 0;
24642481
for (int Idx = 0; Idx < NumTypesToAdd; ++Idx) {
2482+
int nodeIndex = type->getNumChildren() - Idx - 1;
2483+
if (type->getChild(nodeIndex)->getKind() == Node::Kind::ImplSendingResult) {
2484+
implSendingResultIndexAdjustment = 1;
2485+
}
2486+
nodeIndex -= implSendingResultIndexAdjustment;
2487+
24652488
NodePointer ConvTy = popNode(Node::Kind::Type);
24662489
if (!ConvTy)
24672490
return nullptr;
2468-
type->getChild(type->getNumChildren() - Idx - 1)->addChild(ConvTy, *this);
2491+
type->getChild(nodeIndex)->addChild(ConvTy, *this);
24692492
}
2470-
2493+
24712494
return createType(type);
24722495
}
24732496

test/Concurrency/sending_mangling.swift

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
// RUN: %target-swift-frontend %s -emit-silgen -swift-version 6 | swift-demangle | %FileCheck -check-prefix=CHECK %s
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend %s -emit-silgen -swift-version 6 | swift-demangle | %FileCheck %s
3+
// RUN: %target-swift-frontend %s -emit-silgen -swift-version 6 | %FileCheck -check-prefix=SIL %s
24

35
// REQUIRES: concurrency
46
// REQUIRES: asserts
@@ -110,3 +112,18 @@ struct ConstructorSharedTest {
110112
// CHECK: sil hidden [ossa] @sending_mangling.ConstructorSharedTest.functionSuppressed(sending_mangling.NonSendableKlass) -> () : $@convention(method) (@sil_sending @guaranteed NonSendableKlass, ConstructorSharedTest) -> () {
111113
func functionSuppressed(_ x: __shared sending NonSendableKlass) {}
112114
}
115+
116+
// Make sure that we produce the appropriate reabstraction thunk.
117+
func reabstractionThunkTest_takeSendingReturnSending<T>(
118+
_ x: sending T) -> sending T { fatalError() }
119+
func reabstractionThunkTest_reabstractionThunkGenerator<T>(
120+
_ x: sending T,
121+
_ f: (sending T) -> T) {}
122+
123+
// CHECK: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @reabstraction thunk helper from @escaping @callee_guaranteed (@in sending sending_mangling.NonSendableKlass) -> sending (@out sending_mangling.NonSendableKlass) to @escaping @callee_guaranteed (@owned sending sending_mangling.NonSendableKlass) -> sending (@owned sending_mangling.NonSendableKlass) : $@convention(thin) (@sil_sending @owned NonSendableKlass, @guaranteed @callee_guaranteed (@sil_sending @in NonSendableKlass) -> @sil_sending @out NonSendableKlass) -> @owned NonSendableKlass {
124+
// SIL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s16sending_mangling16NonSendableKlassCACIegiTTr_A2CIegxTTo_TR : $@convention(thin) (@sil_sending @owned NonSendableKlass, @guaranteed @callee_guaranteed (@sil_sending @in NonSendableKlass) -> @sil_sending @out NonSendableKlass) -> @owned NonSendableKlass {
125+
func reabstractionThunkTest() {
126+
reabstractionThunkTest_reabstractionThunkGenerator(
127+
NonSendableKlass(),
128+
reabstractionThunkTest_takeSendingReturnSending)
129+
}

test/Demangle/Inputs/manglings.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,3 +485,5 @@ $s4main4SlabVy$1_SiG ---> main.Slab<2, Swift.Int>
485485
$s$n3_SSBV ---> Builtin.FixedArray<-4, Swift.String>
486486
$s3red7MyActorC3runyxxyYaKACYcYTXEYaKlFZ ---> static red.MyActor.run<A>(@red.MyActor () async throws -> sending A) async throws -> A
487487
$s3red7MyActorC3runyxxyYaKYAYTXEYaKlFZ ---> static red.MyActor.run<A>(@isolated(any) () async throws -> sending A) async throws -> A
488+
$s7ToolKit10TypedValueOACs5Error_pIgHnTTrzo_A2CsAD_pIegHiTrzr_TR ---> {T:} reabstraction thunk helper from @callee_guaranteed @async (@in_guaranteed sending ToolKit.TypedValue) -> sending (@out ToolKit.TypedValue, @error @owned Swift.Error) to @escaping @callee_guaranteed @async (@in sending ToolKit.TypedValue) -> (@out ToolKit.TypedValue, @error @out Swift.Error)
489+
$s16sending_mangling16NonSendableKlassCACIegiTTr_A2CIegxTTo_TR ---> {T:} reabstraction thunk helper from @callee_guaranteed @async (@in_guaranteed sending ToolKit.TypedValue) -> sending (@out ToolKit.TypedValue, @error @owned Swift.Error) to @escaping @callee_guaranteed @async (@in sending ToolKit.TypedValue) -> (@out ToolKit.TypedValue, @error @out Swift.Error)

0 commit comments

Comments
 (0)